forked from espressif/esp-idf
Compare commits
1498 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
024ef51d1a | ||
|
|
4d9778e208 | ||
|
|
6181af2a0b | ||
|
|
abf0cd8421 | ||
|
|
7a83c87c44 | ||
|
|
6ad86f0d67 | ||
|
|
fddebe4bcc | ||
|
|
2102acf266 | ||
|
|
a4ac9bf80b | ||
|
|
6e2601f389 | ||
|
|
ea48f43f87 | ||
|
|
1b0b34247a | ||
|
|
4aaa453b31 | ||
|
|
fe69377782 | ||
|
|
1c9d8744ab | ||
|
|
7db3370e20 | ||
|
|
eece22d075 | ||
|
|
2cc668bbb1 | ||
|
|
ad4a1b600a | ||
|
|
877b407c8c | ||
|
|
5850f423d5 | ||
|
|
ea74033d1e | ||
|
|
7cd1e0ef4b | ||
|
|
f72888544e | ||
|
|
a513ac4dec | ||
|
|
b337b20270 | ||
|
|
8ab96b13af | ||
|
|
50f414f54c | ||
|
|
0dfef8c16c | ||
|
|
6bb1367fe5 | ||
|
|
a286846095 | ||
|
|
2b2dd845ae | ||
|
|
b9f9e681ba | ||
|
|
3429241e1a | ||
|
|
455a7784a9 | ||
|
|
7d9a20e714 | ||
|
|
a6980fce4c | ||
|
|
4bd41d4082 | ||
|
|
3302a38432 | ||
|
|
82ef2b9485 | ||
|
|
de461671aa | ||
|
|
aa2f5e4ae5 | ||
|
|
c01dff8263 | ||
|
|
06274ff5a5 | ||
|
|
c62ae777c2 | ||
|
|
abdd8feebb | ||
|
|
3b8c9a407f | ||
|
|
6451c57e52 | ||
|
|
432b25f755 | ||
|
|
6739d5b99f | ||
|
|
d3eede2110 | ||
|
|
ecbe5a66f2 | ||
|
|
4e5e154603 | ||
|
|
6d061ec903 | ||
|
|
fabe0493c2 | ||
|
|
66199b1efe | ||
|
|
23f933a78d | ||
|
|
3b3c3210a6 | ||
|
|
ae09a46cb8 | ||
|
|
4d67a2ba8b | ||
|
|
98f8594151 | ||
|
|
c025dfbfa7 | ||
|
|
f3687f7177 | ||
|
|
8f43567a68 | ||
|
|
f36c909528 | ||
|
|
cd83bfb31c | ||
|
|
c6420792f2 | ||
|
|
290c40a4ab | ||
|
|
13dfb5568d | ||
|
|
d9c649d26e | ||
|
|
75115e1d83 | ||
|
|
c17e05040a | ||
|
|
63e0140ae6 | ||
|
|
1671879b7a | ||
|
|
ff81e17504 | ||
|
|
708539c559 | ||
|
|
36b3963efb | ||
|
|
b582697889 | ||
|
|
7dfb1c2e97 | ||
|
|
c057f067c7 | ||
|
|
ce7d0a7015 | ||
|
|
d772e1489b | ||
|
|
dca0377e19 | ||
|
|
cbb71baca9 | ||
|
|
045307ea0f | ||
|
|
f29768c404 | ||
|
|
c0f155f6ff | ||
|
|
8dede8f8a4 | ||
|
|
d28ee9a25e | ||
|
|
c3544dc090 | ||
|
|
3c90032369 | ||
|
|
e91d436e45 | ||
|
|
de28d3a655 | ||
|
|
e76c187efb | ||
|
|
e35ebbf813 | ||
|
|
04f7d96623 | ||
|
|
55693b1168 | ||
|
|
26dec992eb | ||
|
|
d3fde5188e | ||
|
|
3b583c150f | ||
|
|
1405fd1fef | ||
|
|
adfb289e81 | ||
|
|
a51f378ecc | ||
|
|
b5d1eb42b4 | ||
|
|
678ec0bd04 | ||
|
|
12a7293b31 | ||
|
|
bb0298bc71 | ||
|
|
abf87b000d | ||
|
|
7eaf1c76dc | ||
|
|
770c2ade05 | ||
|
|
95b62ef980 | ||
|
|
4db4e28b6e | ||
|
|
bfdfcbfaef | ||
|
|
21964a42fb | ||
|
|
4bd5b0c91a | ||
|
|
8f3d1d3184 | ||
|
|
4494e15ecf | ||
|
|
ad890aa5ea | ||
|
|
cd13c9e95d | ||
|
|
eb14284c92 | ||
|
|
61c7bd3c3a | ||
|
|
6c139c8ffb | ||
|
|
997fbf9e18 | ||
|
|
2fc4413dae | ||
|
|
6648ff427c | ||
|
|
5023e30a33 | ||
|
|
9cea5ea075 | ||
|
|
34d0b0086e | ||
|
|
39c546d63f | ||
|
|
413f05ce09 | ||
|
|
578e93803a | ||
|
|
fe44bc9e79 | ||
|
|
174c313d3d | ||
|
|
dd5401749d | ||
|
|
01c4a980ee | ||
|
|
25f05bef71 | ||
|
|
24cfe78962 | ||
|
|
4c9fdb7c52 | ||
|
|
0eb5c06ad4 | ||
|
|
7c7edab328 | ||
|
|
22c3877183 | ||
|
|
57af0d70d3 | ||
|
|
10c2e984dc | ||
|
|
dcd5c5bb73 | ||
|
|
473f2cff51 | ||
|
|
a65944a8cb | ||
|
|
97eef61184 | ||
|
|
2664291ba5 | ||
|
|
483411fd1a | ||
|
|
554237bf5e | ||
|
|
5fd7bd14db | ||
|
|
3aa2b571ae | ||
|
|
e8b7670db3 | ||
|
|
9893b71096 | ||
|
|
cf917567e9 | ||
|
|
2c334b46e0 | ||
|
|
0017e75bda | ||
|
|
7093c59a74 | ||
|
|
02460ff864 | ||
|
|
c61fdff729 | ||
|
|
777816cb99 | ||
|
|
89fea85a45 | ||
|
|
b748a63a43 | ||
|
|
d07a149e2c | ||
|
|
c78aa138b0 | ||
|
|
e8adb5ab57 | ||
|
|
627bc23b1c | ||
|
|
96e6839745 | ||
|
|
2d5162dc3c | ||
|
|
732a5fd0b2 | ||
|
|
04acc88023 | ||
|
|
b8e2edc99f | ||
|
|
f21275b910 | ||
|
|
0a678ebe8c | ||
|
|
21c7fc624a | ||
|
|
aaa891ada9 | ||
|
|
a4c76671c2 | ||
|
|
f512923791 | ||
|
|
e6f8837152 | ||
|
|
5e3b30da3a | ||
|
|
b6a2329f0f | ||
|
|
eea2788f5a | ||
|
|
385c61e183 | ||
|
|
39fe51924e | ||
|
|
d8aae55eeb | ||
|
|
67336672bd | ||
|
|
813395adcb | ||
|
|
2173ad3b45 | ||
|
|
4dd81fddd8 | ||
|
|
93395a3370 | ||
|
|
4f7e4dd0f5 | ||
|
|
33500f2561 | ||
|
|
32ad1e676d | ||
|
|
8e467801bc | ||
|
|
c6bb239f0c | ||
|
|
74f78540ae | ||
|
|
1d0c909daf | ||
|
|
d193424ae8 | ||
|
|
03e3b137bf | ||
|
|
6bc9cd39e9 | ||
|
|
d4462664b7 | ||
|
|
14aa1d1b3e | ||
|
|
adc590ff69 | ||
|
|
36ccdee6ec | ||
|
|
95c150fe2c | ||
|
|
fbe89a0833 | ||
|
|
b4a29f5240 | ||
|
|
374d03093c | ||
|
|
632bd0bb4f | ||
|
|
15072028c4 | ||
|
|
fab35cb307 | ||
|
|
74aff89918 | ||
|
|
6f3f3bb30c | ||
|
|
a14f22f65b | ||
|
|
ac412feb69 | ||
|
|
b022232e84 | ||
|
|
0b257cfcef | ||
|
|
92b9ed8342 | ||
|
|
5305842763 | ||
|
|
0fca7769e8 | ||
|
|
3c28283377 | ||
|
|
aea18f6e74 | ||
|
|
1916610b83 | ||
|
|
12b1c99962 | ||
|
|
0073ff3acd | ||
|
|
2ea4d7fd02 | ||
|
|
7eb570b039 | ||
|
|
b1df4c47f9 | ||
|
|
0865819cf9 | ||
|
|
12e3992ae2 | ||
|
|
1ebf907658 | ||
|
|
9ae3ecc72c | ||
|
|
a6b163c954 | ||
|
|
7c155ab647 | ||
|
|
9a8a82e857 | ||
|
|
16b23a407c | ||
|
|
0b6598c492 | ||
|
|
90c43ea95e | ||
|
|
30c2fca25a | ||
|
|
efbd2805e2 | ||
|
|
97e3c0fec4 | ||
|
|
31ec0a7c44 | ||
|
|
d3a2d6aedc | ||
|
|
26015f5d88 | ||
|
|
865b21d5a1 | ||
|
|
3c2d54ead0 | ||
|
|
0564263e5b | ||
|
|
3128f2b004 | ||
|
|
f7e2e456e4 | ||
|
|
680a0d1306 | ||
|
|
0b3646f26e | ||
|
|
0501507d6b | ||
|
|
f8b5c29346 | ||
|
|
57f911033d | ||
|
|
2bb67985dc | ||
|
|
6e2e456d62 | ||
|
|
4676d159ad | ||
|
|
0b2962f41e | ||
|
|
557dafda07 | ||
|
|
0bbc60618b | ||
|
|
e62b255813 | ||
|
|
8aa5082baa | ||
|
|
66647bb5bd | ||
|
|
46d8ece20e | ||
|
|
03c14809f9 | ||
|
|
5ae9647667 | ||
|
|
fb7b218091 | ||
|
|
5508826509 | ||
|
|
799be9fa3a | ||
|
|
963c3aa16a | ||
|
|
3c8235d40d | ||
|
|
f4d5d151aa | ||
|
|
a14bef8f8a | ||
|
|
5e6714dd51 | ||
|
|
df2dc908f0 | ||
|
|
ce8ec337eb | ||
|
|
4d8ca3beaa | ||
|
|
f9ac7657e3 | ||
|
|
71ab455c87 | ||
|
|
7776d3e065 | ||
|
|
8c25a0fd9d | ||
|
|
905180667c | ||
|
|
ad25997349 | ||
|
|
47a0b88f6e | ||
|
|
469d390d46 | ||
|
|
f7a9a2f50b | ||
|
|
382999b378 | ||
|
|
1989917f71 | ||
|
|
1896381501 | ||
|
|
c47cc63489 | ||
|
|
075446318d | ||
|
|
48ae7ab500 | ||
|
|
dd8681d8fc | ||
|
|
81777a9ffe | ||
|
|
3684e6ddfd | ||
|
|
53b0b03e63 | ||
|
|
cdf8836ceb | ||
|
|
455bb4271e | ||
|
|
0d00a1ba01 | ||
|
|
7f751fd0fe | ||
|
|
6538252552 | ||
|
|
72da7aa53b | ||
|
|
ea19838d3a | ||
|
|
27711b7c22 | ||
|
|
ed20560cc4 | ||
|
|
f20135af54 | ||
|
|
786573fb2d | ||
|
|
4c0f90bfae | ||
|
|
4b71d9cb35 | ||
|
|
3efbbab2cf | ||
|
|
a2ace698ed | ||
|
|
e5feeb195f | ||
|
|
d8fb30c930 | ||
|
|
a8b75ed974 | ||
|
|
5bd7e655b9 | ||
|
|
08f11e4c53 | ||
|
|
3168ad10e7 | ||
|
|
dd3f18d2d8 | ||
|
|
ca9f62ad77 | ||
|
|
e53d307814 | ||
|
|
5c9c08eabb | ||
|
|
233fde166b | ||
|
|
7d40f17d1d | ||
|
|
ad66fbe5ad | ||
|
|
ee9fb10e29 | ||
|
|
6eedbfa9be | ||
|
|
9052c6e9ee | ||
|
|
ad1790fe3e | ||
|
|
1895460406 | ||
|
|
fec2f534d5 | ||
|
|
b018a3ce8e | ||
|
|
142756615b | ||
|
|
b24ac487cb | ||
|
|
9aa0e29079 | ||
|
|
e4811216ff | ||
|
|
d3a0580bef | ||
|
|
2126f6c8b7 | ||
|
|
9f151d745e | ||
|
|
aece3d6fc6 | ||
|
|
50b3ce616f | ||
|
|
39ddc7b836 | ||
|
|
23f836659d | ||
|
|
4a3e160888 | ||
|
|
dd73a40556 | ||
|
|
ff4a5a1406 | ||
|
|
d6842e537c | ||
|
|
5fbea86a9e | ||
|
|
8eb9f947e8 | ||
|
|
61da8595ca | ||
|
|
2d8a8bc141 | ||
|
|
1eed54c7cd | ||
|
|
8a2ff5a16d | ||
|
|
d512d6100c | ||
|
|
356e01545c | ||
|
|
0c01ef68f1 | ||
|
|
478591b842 | ||
|
|
8d2199e36c | ||
|
|
f04e62e6cc | ||
|
|
23448e7121 | ||
|
|
63091a2358 | ||
|
|
ae48cbd8c4 | ||
|
|
daa2b7cbc9 | ||
|
|
babeed4170 | ||
|
|
c592714679 | ||
|
|
a98d07d650 | ||
|
|
b455b0246c | ||
|
|
919bb747f8 | ||
|
|
69a7cfa976 | ||
|
|
a2e0c2432e | ||
|
|
8c26dd8d38 | ||
|
|
0c31bdf643 | ||
|
|
ee59fa75f4 | ||
|
|
758281dfed | ||
|
|
59540eeae1 | ||
|
|
6c86586e97 | ||
|
|
833102cbf3 | ||
|
|
89e0ecc272 | ||
|
|
2e06c6ba38 | ||
|
|
0e701e1cac | ||
|
|
5eb8eb3855 | ||
|
|
a3f6728797 | ||
|
|
2927688eba | ||
|
|
26d1a23308 | ||
|
|
881157e1ed | ||
|
|
2e78b397bc | ||
|
|
e9f8e03309 | ||
|
|
315b3f979f | ||
|
|
fb70126bc8 | ||
|
|
c4b3f6bbbc | ||
|
|
a54791846b | ||
|
|
b877216fef | ||
|
|
433ff1474e | ||
|
|
f89de9c5af | ||
|
|
8615dbd486 | ||
|
|
d5464074dd | ||
|
|
5c1c6d2c32 | ||
|
|
ca57a86f20 | ||
|
|
633cd49f88 | ||
|
|
1820069943 | ||
|
|
6421479dab | ||
|
|
11a994d5d8 | ||
|
|
0106feeeda | ||
|
|
37fbe9efb3 | ||
|
|
9dd5f2a952 | ||
|
|
084c14f1e4 | ||
|
|
3fba6f4392 | ||
|
|
5b5a4355e7 | ||
|
|
47f4a09704 | ||
|
|
44ce833d76 | ||
|
|
d418776982 | ||
|
|
9398d1b1cc | ||
|
|
1440c866fc | ||
|
|
6fb430f45e | ||
|
|
3f889de5ab | ||
|
|
edd924f273 | ||
|
|
c1b06bf0a2 | ||
|
|
ecf720d3b3 | ||
|
|
b1c754bbb5 | ||
|
|
5c4f707a33 | ||
|
|
339267ffc9 | ||
|
|
0efaa4f4b8 | ||
|
|
4f909b8ecc | ||
|
|
0bfe08578b | ||
|
|
3708e15ea9 | ||
|
|
0e7f7a2112 | ||
|
|
a575b9e893 | ||
|
|
2250fee01a | ||
|
|
1b9f477b15 | ||
|
|
ed01eb2df1 | ||
|
|
4491dd0e2a | ||
|
|
6ca2934843 | ||
|
|
9c630b759f | ||
|
|
f5b221b9fb | ||
|
|
e4b9563dac | ||
|
|
718969f6ed | ||
|
|
a4c3f876ab | ||
|
|
e387a16e51 | ||
|
|
079138201d | ||
|
|
a69a798878 | ||
|
|
c943fabcda | ||
|
|
1cbc2fa046 | ||
|
|
5b2888e113 | ||
|
|
845cd09570 | ||
|
|
23455de4c2 | ||
|
|
6e1150473e | ||
|
|
489701eb2d | ||
|
|
0b264f4f7b | ||
|
|
61c6ce86d2 | ||
|
|
1b38494df4 | ||
|
|
e2d05d8592 | ||
|
|
8e4a8e1703 | ||
|
|
99d6984800 | ||
|
|
7853893731 | ||
|
|
ded13ac8e6 | ||
|
|
9017c408ac | ||
|
|
c9ef32a0f2 | ||
|
|
24af07fd13 | ||
|
|
ad1d4500f9 | ||
|
|
2e7748d625 | ||
|
|
0feb3633fc | ||
|
|
7778273314 | ||
|
|
5677149833 | ||
|
|
6b5e734901 | ||
|
|
d6fcec73b2 | ||
|
|
daf58e3852 | ||
|
|
f867e0671e | ||
|
|
8c7dfef317 | ||
|
|
56514d5ab2 | ||
|
|
899f61f4a2 | ||
|
|
ee318d42ae | ||
|
|
790a3d9ab3 | ||
|
|
c2a356f23c | ||
|
|
d98b99f4f0 | ||
|
|
be994740b4 | ||
|
|
0fb2ab9f5c | ||
|
|
b1cac83f61 | ||
|
|
6f578796d3 | ||
|
|
6c41080fd9 | ||
|
|
63e9806d85 | ||
|
|
3922ce47b2 | ||
|
|
83442526e0 | ||
|
|
2e3ca1c2f7 | ||
|
|
bf3093feca | ||
|
|
16de41941e | ||
|
|
b9a6d276a2 | ||
|
|
c47bc43afd | ||
|
|
2407faf6c6 | ||
|
|
19fa6e254d | ||
|
|
189543f317 | ||
|
|
5e96070c27 | ||
|
|
4f7314a760 | ||
|
|
03551ec2da | ||
|
|
7883a5bae5 | ||
|
|
9c7cc86793 | ||
|
|
d0b10ba2dd | ||
|
|
2b41c1b8b2 | ||
|
|
6b87419d42 | ||
|
|
eb8324e2c2 | ||
|
|
79d6d9f701 | ||
|
|
370cf5493f | ||
|
|
3783e28f0e | ||
|
|
76e61ded30 | ||
|
|
d245f016ea | ||
|
|
2350288a33 | ||
|
|
d0fccbce15 | ||
|
|
5462d98e5a | ||
|
|
8bcd341fca | ||
|
|
c1370c5561 | ||
|
|
48c4a10827 | ||
|
|
156845f754 | ||
|
|
0b79a108b8 | ||
|
|
ade7ee2092 | ||
|
|
1c08cf2f79 | ||
|
|
3cfe738fcf | ||
|
|
2d7681249a | ||
|
|
06e03ff52e | ||
|
|
e6b09dc258 | ||
|
|
665dcc5712 | ||
|
|
9496fda662 | ||
|
|
948a2ba23a | ||
|
|
6395081503 | ||
|
|
45571b3c38 | ||
|
|
41eca2c67b | ||
|
|
ff1fa8a323 | ||
|
|
1e44f72e98 | ||
|
|
c1a6d55116 | ||
|
|
da977149f6 | ||
|
|
6d0fd80af4 | ||
|
|
6a39bc6996 | ||
|
|
835fa31d56 | ||
|
|
d049fd3929 | ||
|
|
d2e58193d2 | ||
|
|
3ad6dbbaa1 | ||
|
|
15651b5923 | ||
|
|
5ddf6daa98 | ||
|
|
05fcdcfedb | ||
|
|
28aa7ba658 | ||
|
|
a1915f7f87 | ||
|
|
e8b194d5e5 | ||
|
|
794f7dd294 | ||
|
|
abb7668af7 | ||
|
|
99f4c697ee | ||
|
|
4cfbe80b0f | ||
|
|
578b627d9b | ||
|
|
ab5915ff8b | ||
|
|
2f9772860a | ||
|
|
3a2fbda35c | ||
|
|
57817f7c53 | ||
|
|
2cffaf9cc8 | ||
|
|
a760eb3980 | ||
|
|
de8ecdd3c1 | ||
|
|
168190d7e4 | ||
|
|
9dbdab5c9a | ||
|
|
4f3ff1cf7e | ||
|
|
bae0149920 | ||
|
|
51cd654658 | ||
|
|
198889ad26 | ||
|
|
cca883490e | ||
|
|
ba08d1ae25 | ||
|
|
41ce99db32 | ||
|
|
4c86aba160 | ||
|
|
7ba6be782e | ||
|
|
59e0f63d37 | ||
|
|
d031530196 | ||
|
|
6a8a9a0272 | ||
|
|
1597f7a035 | ||
|
|
99849ca2cc | ||
|
|
93e72649dc | ||
|
|
4854dcf0eb | ||
|
|
65fe6ab320 | ||
|
|
c01dedcb06 | ||
|
|
bb584c4333 | ||
|
|
4853df9c83 | ||
|
|
1ed584f896 | ||
|
|
d6fafd00db | ||
|
|
b00b75db7e | ||
|
|
2c165aba36 | ||
|
|
b62f8b42d4 | ||
|
|
7a527896dc | ||
|
|
7b02eae9e6 | ||
|
|
461aab3e75 | ||
|
|
576052e5c2 | ||
|
|
126d164283 | ||
|
|
628bad1dbf | ||
|
|
370f4b8556 | ||
|
|
609d852834 | ||
|
|
616d1d32f1 | ||
|
|
83184bd52b | ||
|
|
35115885c5 | ||
|
|
88ddf5aefa | ||
|
|
eac80b0651 | ||
|
|
3b854fe46a | ||
|
|
71daf49e39 | ||
|
|
d246836cfc | ||
|
|
9d8e110202 | ||
|
|
87d0eb0fdb | ||
|
|
3984d96acb | ||
|
|
847092e483 | ||
|
|
eec743d04c | ||
|
|
9d5f4e877e | ||
|
|
70d39aa105 | ||
|
|
dc9646bc53 | ||
|
|
55726385a4 | ||
|
|
712f53176d | ||
|
|
6f0a494cae | ||
|
|
1e117dc3d3 | ||
|
|
293ad4cd36 | ||
|
|
3f3cf397f7 | ||
|
|
1cb2081d99 | ||
|
|
25e7f3a303 | ||
|
|
5a2033c4e3 | ||
|
|
5e2ae7ac19 | ||
|
|
d242251295 | ||
|
|
f3450abf3d | ||
|
|
d045187c0f | ||
|
|
1037a50abe | ||
|
|
3ed16758c0 | ||
|
|
d288a3d053 | ||
|
|
f1390fa7c9 | ||
|
|
953b12b4c0 | ||
|
|
4f637034e8 | ||
|
|
49be64a716 | ||
|
|
487548e7dd | ||
|
|
cbff82cc44 | ||
|
|
aba262b18b | ||
|
|
69ee1de9fa | ||
|
|
5e87cdec7e | ||
|
|
fd11beebcd | ||
|
|
7ae7a56457 | ||
|
|
2e9c06b584 | ||
|
|
d5c57d1d10 | ||
|
|
8f3c74353a | ||
|
|
071615b059 | ||
|
|
78161a1fe3 | ||
|
|
d60ff9b6f6 | ||
|
|
311b7040d5 | ||
|
|
2a22dc082b | ||
|
|
6380245d3d | ||
|
|
2a4b150017 | ||
|
|
bbe1bceda8 | ||
|
|
9a378bca0e | ||
|
|
1c60a0450e | ||
|
|
bf2a568924 | ||
|
|
bab1d49f1f | ||
|
|
f0efb41b57 | ||
|
|
f504e23d0f | ||
|
|
1be09039e3 | ||
|
|
4c6ccf1c23 | ||
|
|
e0e6966be0 | ||
|
|
8185b0f806 | ||
|
|
bf57594ebe | ||
|
|
f68e1c22ab | ||
|
|
9fd7908bbe | ||
|
|
cf311d81ee | ||
|
|
8ba75a1e9f | ||
|
|
a283042258 | ||
|
|
bf7fbdf3cf | ||
|
|
d6ec6d1ae5 | ||
|
|
5e1cdd3422 | ||
|
|
19a2ee3740 | ||
|
|
8ca6e37c12 | ||
|
|
baa6a477c5 | ||
|
|
c1802eaa98 | ||
|
|
f807d16310 | ||
|
|
cb9ef19d3b | ||
|
|
2c34ab3374 | ||
|
|
9dc908d105 | ||
|
|
ae8c37e0b6 | ||
|
|
32fa94935d | ||
|
|
655fd2986a | ||
|
|
221dc13535 | ||
|
|
505282bab1 | ||
|
|
a1542421c0 | ||
|
|
e3eff5deb9 | ||
|
|
81e721ebcb | ||
|
|
a00762f1f9 | ||
|
|
cbc7d1814c | ||
|
|
dbc5edac7e | ||
|
|
25e4e21226 | ||
|
|
c277735e6e | ||
|
|
5933ebc6b6 | ||
|
|
94d2f77643 | ||
|
|
b98405f9d9 | ||
|
|
20fd57f147 | ||
|
|
13d802262a | ||
|
|
b57aecdfe9 | ||
|
|
b3f6cd08db | ||
|
|
ce8b52617e | ||
|
|
6dc77bc55c | ||
|
|
b1db2721dc | ||
|
|
0dff9ed79d | ||
|
|
60d7440781 | ||
|
|
a35e4f5923 | ||
|
|
69df54a28c | ||
|
|
9a774848d4 | ||
|
|
1613c180e0 | ||
|
|
a241197067 | ||
|
|
ec40053720 | ||
|
|
3cd9cb8911 | ||
|
|
2dbae95a7e | ||
|
|
c852e9958b | ||
|
|
c8685c2002 | ||
|
|
65f57e5da7 | ||
|
|
5f47b85b87 | ||
|
|
004aadfe70 | ||
|
|
9423390c2e | ||
|
|
f394632319 | ||
|
|
667d0ef319 | ||
|
|
ceb8566970 | ||
|
|
f62b83fb77 | ||
|
|
822ed84225 | ||
|
|
a9d5e26748 | ||
|
|
506c8cd964 | ||
|
|
9eb135fd73 | ||
|
|
ab3677d64c | ||
|
|
bd20288b81 | ||
|
|
d925b96daf | ||
|
|
df419fd862 | ||
|
|
954ffa102f | ||
|
|
bdf4006da7 | ||
|
|
5c1928b14d | ||
|
|
e0040af7e5 | ||
|
|
c6ec70b67b | ||
|
|
c110795718 | ||
|
|
099e3030bf | ||
|
|
60ac08115f | ||
|
|
6ff431d464 | ||
|
|
9b2cad4174 | ||
|
|
2092d14e45 | ||
|
|
ad555d68d3 | ||
|
|
281a9c2761 | ||
|
|
1abf2c4ed7 | ||
|
|
ba96c0d2e9 | ||
|
|
59f3684dee | ||
|
|
1b9a4a8139 | ||
|
|
144a1567e3 | ||
|
|
7c7f255b98 | ||
|
|
7114f933bb | ||
|
|
72453e3e6b | ||
|
|
a8dd1dfcf2 | ||
|
|
527767d31c | ||
|
|
6010ea713f | ||
|
|
f4df733edf | ||
|
|
d2c61cae8c | ||
|
|
758a9e5f06 | ||
|
|
4c83238a85 | ||
|
|
5a9801aca7 | ||
|
|
5a14e8addf | ||
|
|
9f33d8f5c0 | ||
|
|
f9d2d63e75 | ||
|
|
3a3d4276f8 | ||
|
|
06e2a1d4e1 | ||
|
|
de5279ce6c | ||
|
|
01e94998c4 | ||
|
|
f6de7ea764 | ||
|
|
9d9e758756 | ||
|
|
b9c678f713 | ||
|
|
5b4361f60a | ||
|
|
fc2883a59a | ||
|
|
9a3f9af2db | ||
|
|
72422b32dc | ||
|
|
fd0d28afc3 | ||
|
|
ff8ce12787 | ||
|
|
1173106a20 | ||
|
|
c9a0b9a45c | ||
|
|
db1e86b3d9 | ||
|
|
55aa82f814 | ||
|
|
3f27c09728 | ||
|
|
6e3b7f4ea2 | ||
|
|
73f4e8b2af | ||
|
|
88b264cfce | ||
|
|
a902e2a9de | ||
|
|
ac87ddfb05 | ||
|
|
16f2b119eb | ||
|
|
7f2c6a9d80 | ||
|
|
1818af1c3e | ||
|
|
0dbc11e37d | ||
|
|
58d902eb78 | ||
|
|
d0801fdbab | ||
|
|
9f9d92b2df | ||
|
|
7a93422089 | ||
|
|
7dc322273c | ||
|
|
19273c7b2d | ||
|
|
d7eb709a9c | ||
|
|
a5ad8090cf | ||
|
|
35ae2cd1a5 | ||
|
|
5eb2d16acd | ||
|
|
340b14f0b7 | ||
|
|
1cdd082a9e | ||
|
|
160e81e901 | ||
|
|
b5f03a36d5 | ||
|
|
55e0690f69 | ||
|
|
4ea18083f7 | ||
|
|
b649b48eae | ||
|
|
c17ee8a914 | ||
|
|
1bcd90d45d | ||
|
|
422e95db9c | ||
|
|
7a41ab6982 | ||
|
|
e5ceddabac | ||
|
|
be53a6950c | ||
|
|
79482bbee7 | ||
|
|
f60e54497c | ||
|
|
7e433ae3f4 | ||
|
|
3b937c5ef8 | ||
|
|
f97f198c9d | ||
|
|
6d502cebe9 | ||
|
|
79646f41b5 | ||
|
|
225e31b6de | ||
|
|
452bee7181 | ||
|
|
303ab23116 | ||
|
|
a97e076dec | ||
|
|
6db1482cd5 | ||
|
|
7571b8c2e4 | ||
|
|
c533099e08 | ||
|
|
f7aeef7111 | ||
|
|
13e7e69239 | ||
|
|
ca76f53283 | ||
|
|
9ccb104895 | ||
|
|
85aac3afa6 | ||
|
|
f7fb8b264f | ||
|
|
9ec0fea8e1 | ||
|
|
50f178c1ce | ||
|
|
137c027274 | ||
|
|
38303052f3 | ||
|
|
15d96eccdb | ||
|
|
0b75ff5a6d | ||
|
|
83a3ce882f | ||
|
|
8693e805df | ||
|
|
1d05f41a70 | ||
|
|
180f4d0929 | ||
|
|
5ac7810480 | ||
|
|
a3c4a70ba3 | ||
|
|
2a73783bc6 | ||
|
|
df6edb50e9 | ||
|
|
6cae05d058 | ||
|
|
cf6fc7c741 | ||
|
|
46a39b1e0f | ||
|
|
8b2f933a51 | ||
|
|
2393d829de | ||
|
|
db007fbb2e | ||
|
|
d0c9c1de57 | ||
|
|
190b6d629b | ||
|
|
dfcb241850 | ||
|
|
2561b68af8 | ||
|
|
c48612e516 | ||
|
|
595bd2e3c4 | ||
|
|
d390449371 | ||
|
|
e05fe28574 | ||
|
|
383d987697 | ||
|
|
720a6c1e54 | ||
|
|
46c81ded73 | ||
|
|
4bf0465dab | ||
|
|
cc39b7b286 | ||
|
|
d467eabadb | ||
|
|
235eceea06 | ||
|
|
6a1dbc3f1c | ||
|
|
3b432735c6 | ||
|
|
07fc868ea6 | ||
|
|
1cc1d9d721 | ||
|
|
1ca82de638 | ||
|
|
4261fc5ef7 | ||
|
|
7681dbec93 | ||
|
|
39e924b664 | ||
|
|
586c17f831 | ||
|
|
4079d1e008 | ||
|
|
1d47755588 | ||
|
|
fc6be12a8f | ||
|
|
9cc9710a27 | ||
|
|
4ed6404e9f | ||
|
|
ed0612c56b | ||
|
|
a485af0e2d | ||
|
|
bf20b958a9 | ||
|
|
c6016952e8 | ||
|
|
a8fb9f2b84 | ||
|
|
311a4cd678 | ||
|
|
d4b5bd347d | ||
|
|
dd0585e84e | ||
|
|
a86c431f98 | ||
|
|
bf61f6de55 | ||
|
|
4e9e8f52ac | ||
|
|
fa3e4103ab | ||
|
|
4d81e40413 | ||
|
|
8cd48d9f9c | ||
|
|
1561c02ba9 | ||
|
|
fa57720cdf | ||
|
|
a76b65ed95 | ||
|
|
b08113d2b4 | ||
|
|
ab92d43bc6 | ||
|
|
0245a2028c | ||
|
|
659ec8facb | ||
|
|
139fdcb9ec | ||
|
|
4dcf3709b0 | ||
|
|
5a81c06e39 | ||
|
|
1f6585dd4f | ||
|
|
0b265dc2a7 | ||
|
|
541b142654 | ||
|
|
6d4ab76db2 | ||
|
|
4db29f74a0 | ||
|
|
a0feea8daa | ||
|
|
6e97936bac | ||
|
|
51021b06f8 | ||
|
|
3edcd29a83 | ||
|
|
2f7288ff03 | ||
|
|
8ab4e11840 | ||
|
|
1cc0b3000b | ||
|
|
36f29017b6 | ||
|
|
68d370542a | ||
|
|
f87be70d51 | ||
|
|
6b687b43f4 | ||
|
|
2b196b4f3e | ||
|
|
37365cef95 | ||
|
|
645717b147 | ||
|
|
b092e42740 | ||
|
|
f3a44aa4db | ||
|
|
7548b8c622 | ||
|
|
3bbe41c34d | ||
|
|
e332407785 | ||
|
|
d73448f57f | ||
|
|
acafa9aaa8 | ||
|
|
b0ca2feabc | ||
|
|
9e6e6b8ff6 | ||
|
|
6472f193ab | ||
|
|
02f5bb9442 | ||
|
|
d116adf260 | ||
|
|
d19d7107d3 | ||
|
|
3366c98d39 | ||
|
|
b0f3b730aa | ||
|
|
936b02216b | ||
|
|
2ab64e1ecc | ||
|
|
12dd886ee1 | ||
|
|
a35e2d42f0 | ||
|
|
f12be7ebd8 | ||
|
|
5e428f21b6 | ||
|
|
ceea97495f | ||
|
|
78d0849426 | ||
|
|
872a481cf1 | ||
|
|
84635a160e | ||
|
|
24b4c17ead | ||
|
|
4eeb2bc41e | ||
|
|
c90e3c7f9e | ||
|
|
637f6fb27e | ||
|
|
13d4734399 | ||
|
|
ca202cbb46 | ||
|
|
8713155e66 | ||
|
|
94f26af17d | ||
|
|
aafaebefb4 | ||
|
|
0b2cea6e9f | ||
|
|
a63383dd19 | ||
|
|
a023b005c6 | ||
|
|
dd3c8487f1 | ||
|
|
19d96d5b26 | ||
|
|
9691fe9dae | ||
|
|
69dbc36a1c | ||
|
|
8b7d1cdc27 | ||
|
|
d1fc5fe432 | ||
|
|
13b81debb3 | ||
|
|
37cbb0bdea | ||
|
|
7dbf01b210 | ||
|
|
60f29236f6 | ||
|
|
8fed003ce5 | ||
|
|
9ae07082ff | ||
|
|
2ed9e2d9a8 | ||
|
|
656543c5ca | ||
|
|
21d2b78105 | ||
|
|
d7599ab16d | ||
|
|
229df65cfc | ||
|
|
521ef3f579 | ||
|
|
cf8c9770a0 | ||
|
|
4d25986aaa | ||
|
|
a2b1f4221b | ||
|
|
dfaac25a37 | ||
|
|
a40e0936e5 | ||
|
|
a8a51a2786 | ||
|
|
0e69a2c446 | ||
|
|
1b25795f5d | ||
|
|
078a16f7b4 | ||
|
|
9a2887c458 | ||
|
|
aa81f047f8 | ||
|
|
3bf5fb8ae7 | ||
|
|
fa1d5bfbc7 | ||
|
|
42787948bb | ||
|
|
adb4be859c | ||
|
|
858fe9815b | ||
|
|
64a2f0ee0b | ||
|
|
c694c5134f | ||
|
|
c36a3e7d06 | ||
|
|
c625f0e906 | ||
|
|
794b4ff578 | ||
|
|
9a7db9ca85 | ||
|
|
751736f902 | ||
|
|
f7af4ddc89 | ||
|
|
2bad1dd594 | ||
|
|
c04f05ee84 | ||
|
|
c15024e629 | ||
|
|
ea4005e673 | ||
|
|
09c7ccfa2c | ||
|
|
0b4fe9dd6d | ||
|
|
572f62928b | ||
|
|
045a53a7e5 | ||
|
|
6eac435723 | ||
|
|
734c1dd954 | ||
|
|
8691b54758 | ||
|
|
bcdebda8e4 | ||
|
|
5a5e19cd8b | ||
|
|
e459f803da | ||
|
|
fe66dd85f0 | ||
|
|
ff1b2c6039 | ||
|
|
7402a1b973 | ||
|
|
64f3893cb9 | ||
|
|
b5de581399 | ||
|
|
f9e9e6b938 | ||
|
|
cc510c1d95 | ||
|
|
57009aaa7f | ||
|
|
f5cebd2666 | ||
|
|
980be385cb | ||
|
|
fdf3db1959 | ||
|
|
9aa9086c8b | ||
|
|
7b77daaea4 | ||
|
|
8dc9e243ae | ||
|
|
177bb340b3 | ||
|
|
341593f7d2 | ||
|
|
ce0382f0c0 | ||
|
|
9858fde4a2 | ||
|
|
48a976ddbf | ||
|
|
c6073cb5de | ||
|
|
08fd07a1ef | ||
|
|
71940dd0ce | ||
|
|
2f6d71ff8c | ||
|
|
eb067ce908 | ||
|
|
07c30f22b5 | ||
|
|
86d8f63005 | ||
|
|
4f4c9030fd | ||
|
|
3269653b94 | ||
|
|
e94ef1d56e | ||
|
|
07f36a9437 | ||
|
|
25db1effd6 | ||
|
|
3aca537157 | ||
|
|
f7cb6fc969 | ||
|
|
208e83def7 | ||
|
|
6fb2515a5d | ||
|
|
f1938a909a | ||
|
|
c441d3630c | ||
|
|
2f0efe1510 | ||
|
|
3b96f68afd | ||
|
|
d7e57eb668 | ||
|
|
155f912433 | ||
|
|
830e5caf4d | ||
|
|
fcba7e278d | ||
|
|
0dff62051f | ||
|
|
cc072f1d8a | ||
|
|
c5793521a0 | ||
|
|
81b18aa8d5 | ||
|
|
1e4f185d29 | ||
|
|
f142da3ced | ||
|
|
d29935b9ce | ||
|
|
6dd3681115 | ||
|
|
3f8d9d71e2 | ||
|
|
aa0cd0ab47 | ||
|
|
13b3c916f3 | ||
|
|
bdd7fb7a13 | ||
|
|
2dda3f57b5 | ||
|
|
cdebf24954 | ||
|
|
8dee0a3f6d | ||
|
|
c3eee0fa52 | ||
|
|
414e5ce1d5 | ||
|
|
cb5f7690a4 | ||
|
|
0aca2506fc | ||
|
|
7340a77689 | ||
|
|
1418f886eb | ||
|
|
178db4bdd9 | ||
|
|
d12078b692 | ||
|
|
fce359b240 | ||
|
|
98a0387854 | ||
|
|
0762b050dd | ||
|
|
314cbcdb67 | ||
|
|
e452278194 | ||
|
|
c8a43508e5 | ||
|
|
b6dd8a55cd | ||
|
|
4e1c56e965 | ||
|
|
599a65657d | ||
|
|
faad29234a | ||
|
|
118984283a | ||
|
|
025bb47302 | ||
|
|
3b489f04f0 | ||
|
|
522f83ae3d | ||
|
|
3051c74488 | ||
|
|
d093dcbbb7 | ||
|
|
c3f7d15246 | ||
|
|
3eaf1ec907 | ||
|
|
7bcd68fb30 | ||
|
|
adca98348e | ||
|
|
9c2ab4559d | ||
|
|
b981b195be | ||
|
|
224acf37f6 | ||
|
|
084248e211 | ||
|
|
5c3ce5b269 | ||
|
|
aa6fe04148 | ||
|
|
acda125e8b | ||
|
|
4ea38327b6 | ||
|
|
b83b0ed06a | ||
|
|
1544965b21 | ||
|
|
8089afd453 | ||
|
|
2d88fc0329 | ||
|
|
90d9f1a74e | ||
|
|
3ec23f1b83 | ||
|
|
2fa00ebd90 | ||
|
|
8bdcf0c5f7 | ||
|
|
15474b9b7e | ||
|
|
a6b3be6734 | ||
|
|
9ed7c4f8bc | ||
|
|
e96d4a0a32 | ||
|
|
e314f42b0c | ||
|
|
4d3ed9efde | ||
|
|
b717e44eb2 | ||
|
|
6602d6b7f2 | ||
|
|
8282c73ac2 | ||
|
|
abecab7525 | ||
|
|
bc4f1c90a7 | ||
|
|
299655e3be | ||
|
|
1540469598 | ||
|
|
c377650cdd | ||
|
|
5035f51c4e | ||
|
|
eb2c633cbf | ||
|
|
47910466ce | ||
|
|
e56b745527 | ||
|
|
c12aeb1127 | ||
|
|
2e319705ec | ||
|
|
fdff6b2b01 | ||
|
|
57f8128718 | ||
|
|
cdd65095e3 | ||
|
|
bc604d14ff | ||
|
|
c534dedf2d | ||
|
|
0aadc58b87 | ||
|
|
a0007ceb79 | ||
|
|
aceb6517c0 | ||
|
|
2cea783ca1 | ||
|
|
97c75a88ae | ||
|
|
3af7872839 | ||
|
|
d0fac3c395 | ||
|
|
04beb8baba | ||
|
|
4ba1b73eba | ||
|
|
cf732bb663 | ||
|
|
f10cc7dc8e | ||
|
|
1cab448c73 | ||
|
|
e1f0c98ef5 | ||
|
|
0df0d74d5d | ||
|
|
f18c1f13b1 | ||
|
|
b8e940d645 | ||
|
|
fe64ea95b4 | ||
|
|
d76868eec1 | ||
|
|
4f71d741ec | ||
|
|
c67ac340c7 | ||
|
|
1d3626c119 | ||
|
|
5784586041 | ||
|
|
bc834820bb | ||
|
|
d472ff5856 | ||
|
|
8c1d1e19c2 | ||
|
|
edf5b10344 | ||
|
|
f0cd38a079 | ||
|
|
12e78e9590 | ||
|
|
bc710e5b88 | ||
|
|
66b31b89ac | ||
|
|
cb33e2a5ae | ||
|
|
8d1f360ca6 | ||
|
|
16a4d56fe5 | ||
|
|
fc6b52574a | ||
|
|
c85be70b9f | ||
|
|
a8b2608dd9 | ||
|
|
ce9e73cd19 | ||
|
|
8d6b782327 | ||
|
|
73944e6800 | ||
|
|
d66f05c61b | ||
|
|
12efd96fb4 | ||
|
|
19af5b7a76 | ||
|
|
079f5faad8 | ||
|
|
f6118c67b0 | ||
|
|
905d27815c | ||
|
|
2d56953ee4 | ||
|
|
fa002b4909 | ||
|
|
234739f51a | ||
|
|
1263cd340e | ||
|
|
f05cd619f4 | ||
|
|
adae42fd85 | ||
|
|
591b7caa95 | ||
|
|
3584fcfc7c | ||
|
|
b6a463e94f | ||
|
|
8ae97a2855 | ||
|
|
6ce1af5898 | ||
|
|
4900c63071 | ||
|
|
6435a71de2 | ||
|
|
cb70ac831f | ||
|
|
99fc760088 | ||
|
|
ec99397c3e | ||
|
|
41514f497a | ||
|
|
124a673a78 | ||
|
|
92b663d9f2 | ||
|
|
abea6c50f1 | ||
|
|
c7f8d206ed | ||
|
|
d9cdc7de58 | ||
|
|
2b722ea468 | ||
|
|
19f61332a9 | ||
|
|
1cc3858dc8 | ||
|
|
413f2c00f6 | ||
|
|
269332f473 | ||
|
|
2119b98469 | ||
|
|
3053518f8a | ||
|
|
d7b4197ade | ||
|
|
a5552b1e21 | ||
|
|
e34fc7a46c | ||
|
|
e7cc1aded5 | ||
|
|
9555ce291e | ||
|
|
41a91d7cb9 | ||
|
|
2d15803f70 | ||
|
|
f30887bc70 | ||
|
|
ffeffcd315 | ||
|
|
90b787636a | ||
|
|
4f2719236f | ||
|
|
19c4996bc8 | ||
|
|
5ffd6155f2 | ||
|
|
0e90983c9f | ||
|
|
0933339e4b | ||
|
|
95403b8803 | ||
|
|
3cd86d6bce | ||
|
|
78392bf76b | ||
|
|
309bd12855 | ||
|
|
d6db871068 | ||
|
|
a038a2b533 | ||
|
|
9e7bc900c5 | ||
|
|
38ff616e4a | ||
|
|
4d8ad3c877 | ||
|
|
305b63209e | ||
|
|
933b6bd94a | ||
|
|
dc2b5d0c96 | ||
|
|
c581229e1d | ||
|
|
9f0f05d520 | ||
|
|
e03b45eb0a | ||
|
|
e229ec0340 | ||
|
|
b6693225c1 | ||
|
|
2c5340d47e | ||
|
|
079d9ea018 | ||
|
|
999e6d4e8f | ||
|
|
42068c3b36 | ||
|
|
54ca573ce4 | ||
|
|
628bde2080 | ||
|
|
f6f23141b3 | ||
|
|
bdf2908057 | ||
|
|
6f1d3ce4a7 | ||
|
|
da56e76255 | ||
|
|
7e201c5527 | ||
|
|
0c130ecf19 | ||
|
|
b3b8334d54 | ||
|
|
587360363c | ||
|
|
401f6e4713 | ||
|
|
38c6256db9 | ||
|
|
68f39c1ed9 | ||
|
|
b14faabfda | ||
|
|
3371083c16 | ||
|
|
84c2e61b12 | ||
|
|
6e6e51426f | ||
|
|
cc7313f216 | ||
|
|
50bd28353d | ||
|
|
329ad14b8c | ||
|
|
c6477ff10d | ||
|
|
95d0ea0d98 | ||
|
|
ff6b8addd9 | ||
|
|
e0f49c2221 | ||
|
|
fd887dbeea | ||
|
|
8dcd78d52f | ||
|
|
6d54fb004d | ||
|
|
5642a8061e | ||
|
|
df1c2f0da5 | ||
|
|
d3d9a8bc28 | ||
|
|
5ede46f213 | ||
|
|
750d6faf51 | ||
|
|
345cf333a8 | ||
|
|
3cd8149288 | ||
|
|
3cca62dfa4 | ||
|
|
a799bb8519 | ||
|
|
7847569672 | ||
|
|
45638b3f98 | ||
|
|
9546ad5b5e | ||
|
|
a90217e201 | ||
|
|
48301909eb | ||
|
|
612aaa69e4 | ||
|
|
74a658c765 | ||
|
|
bb1efe50c3 | ||
|
|
7d254eb3f0 | ||
|
|
fd064e5d88 | ||
|
|
47d73dfe05 | ||
|
|
1ca97f5adb | ||
|
|
6f96b23989 | ||
|
|
86dc0ae808 | ||
|
|
06bff71481 | ||
|
|
89f7752cdd | ||
|
|
78d1fd5306 | ||
|
|
75a11589a1 | ||
|
|
20d33d636b | ||
|
|
cbb26c9532 | ||
|
|
700ed63651 | ||
|
|
d7ea61734b | ||
|
|
d9005e739d | ||
|
|
8e247f3b4c | ||
|
|
3edcf5b096 | ||
|
|
abd4dc7d43 | ||
|
|
5fbfa2a01d | ||
|
|
be11f598bf | ||
|
|
74aff2b9d2 | ||
|
|
f988dc9587 | ||
|
|
9098e64398 | ||
|
|
288f4f63f0 | ||
|
|
60fb9a8c81 | ||
|
|
ae5c563080 | ||
|
|
beff3aab81 | ||
|
|
2b8a493659 | ||
|
|
53146799a0 | ||
|
|
922839d131 | ||
|
|
063e9e8287 | ||
|
|
2c0ceb484b | ||
|
|
1413ec3ff0 | ||
|
|
f37e70ebd6 | ||
|
|
94442708f5 | ||
|
|
8e8caca2e2 | ||
|
|
42827ff869 | ||
|
|
7104284e31 | ||
|
|
4f704ac2fe | ||
|
|
feca308f1f | ||
|
|
6b85040059 | ||
|
|
dfe0dcaed4 | ||
|
|
d3d8c04535 | ||
|
|
39a06319e2 | ||
|
|
0704deca63 | ||
|
|
ede25dbc17 | ||
|
|
5e8849d032 | ||
|
|
2d393f0530 | ||
|
|
c350972eac | ||
|
|
e81ff4f68c | ||
|
|
18ebc6411e | ||
|
|
6eaf595a0e | ||
|
|
0324373cd1 | ||
|
|
c2b63a614e | ||
|
|
de7b2f5a09 | ||
|
|
3f521c4afa | ||
|
|
fcf664276f | ||
|
|
da70611196 | ||
|
|
24df5e2041 | ||
|
|
2182b69b3d | ||
|
|
746ad41d89 | ||
|
|
90cad92b9b | ||
|
|
340a722715 | ||
|
|
19db9ed870 | ||
|
|
d00ef1607e | ||
|
|
0574f2f55a | ||
|
|
9476dc2eb8 | ||
|
|
6a7ec425cb | ||
|
|
c03549e117 | ||
|
|
0403d43b19 | ||
|
|
28d83e766a | ||
|
|
8f82a83c2c | ||
|
|
28fa3c1a70 | ||
|
|
2fdd9ba930 | ||
|
|
eaace9846a | ||
|
|
bee1be67da | ||
|
|
34fa6a60a9 | ||
|
|
1cd572c7b9 | ||
|
|
182184567e | ||
|
|
0aab006bb7 | ||
|
|
7cb55c2c6c | ||
|
|
3ed2d89538 | ||
|
|
f87ebb6d49 | ||
|
|
3ecce07dbc | ||
|
|
1a08abea78 | ||
|
|
02ad223eea | ||
|
|
982b90e77d | ||
|
|
4370794d07 | ||
|
|
72712c00a7 | ||
|
|
f68c8dd687 | ||
|
|
af9b08d863 | ||
|
|
216b831646 | ||
|
|
65445b21dd | ||
|
|
bdd67c98d6 | ||
|
|
6a5f5400f0 | ||
|
|
20b508e62e | ||
|
|
fa476c8ba9 | ||
|
|
03bd5b6d22 | ||
|
|
89097d5f11 | ||
|
|
c56325f43b | ||
|
|
3c792f427b | ||
|
|
ce7b8059de | ||
|
|
9632c8e56c | ||
|
|
6b3bc4d8c5 | ||
|
|
1a6dd44d03 | ||
|
|
5e0a9bfcf2 | ||
|
|
e9199a0320 | ||
|
|
b72d22041c | ||
|
|
d85ff46bdf | ||
|
|
849ba39544 | ||
|
|
685c1084ba | ||
|
|
1447cd4136 | ||
|
|
e5b8854d96 | ||
|
|
19ca66c968 | ||
|
|
fbb654fa68 | ||
|
|
6442601333 | ||
|
|
12fa7472ea | ||
|
|
547fb6ed6c | ||
|
|
9b72441b45 | ||
|
|
4929534448 | ||
|
|
d7db3e6a35 | ||
|
|
5ba6c1b1b7 | ||
|
|
5fab6c36c8 | ||
|
|
d695d40196 | ||
|
|
59b35eb16a | ||
|
|
024a1ce260 | ||
|
|
4de2054541 | ||
|
|
745ecef263 | ||
|
|
99ebc93abb | ||
|
|
e2dd6ebcf0 | ||
|
|
2fe759ce1d | ||
|
|
90e57cdf8f | ||
|
|
924fea7cc0 | ||
|
|
8ee1a05914 | ||
|
|
58aec93dbb | ||
|
|
609c1c2cdb | ||
|
|
1bae606ccc | ||
|
|
c12582c122 | ||
|
|
79bd6af7e7 | ||
|
|
71c09d8f66 | ||
|
|
a20c2f1088 | ||
|
|
ab67378ef3 | ||
|
|
812d4ab4ea | ||
|
|
bde768f13c | ||
|
|
0b30c22162 | ||
|
|
833eb88679 | ||
|
|
e32d4e546a | ||
|
|
5d60a1153d | ||
|
|
ecefb1305a | ||
|
|
034da95abb | ||
|
|
37a68ad605 | ||
|
|
47e83ee65e | ||
|
|
2033068a72 | ||
|
|
d71894bf99 | ||
|
|
df31bb8dfc | ||
|
|
82df5f9aa0 | ||
|
|
a03e75d34c | ||
|
|
5cd3bd5c4b | ||
|
|
eb8cb8d22e | ||
|
|
1c877be609 | ||
|
|
0b37621438 | ||
|
|
12caaed280 | ||
|
|
aae3e84829 | ||
|
|
305bc9fd9c | ||
|
|
6a890e6c49 | ||
|
|
f720e82d40 | ||
|
|
eccf54b939 | ||
|
|
477d71e589 | ||
|
|
66882347e8 | ||
|
|
9c0cd10d48 | ||
|
|
7bdcafe553 | ||
|
|
de587a2e0d | ||
|
|
b97c00f2c1 | ||
|
|
1bcc5438ec | ||
|
|
9c4e43a3a5 | ||
|
|
6c793cb8eb | ||
|
|
9e20d31f89 | ||
|
|
6941b5871a | ||
|
|
877adaab7a | ||
|
|
652ddae44f | ||
|
|
3882937427 | ||
|
|
b80325604d | ||
|
|
cf4aaf6397 | ||
|
|
e1c4a4bfa3 | ||
|
|
d2bc170b86 | ||
|
|
83aea6c833 | ||
|
|
12b72e91af | ||
|
|
5c5f7eb7fe | ||
|
|
f9fd5b6c72 | ||
|
|
59bb9a9a01 | ||
|
|
db9becfa74 | ||
|
|
e475d0539e | ||
|
|
f5d9bfc7ae | ||
|
|
07c8bbca6c | ||
|
|
9fc054bb55 | ||
|
|
1bfedf9816 | ||
|
|
18787fd4fc | ||
|
|
f796b4e58e | ||
|
|
fa6f03f77f | ||
|
|
a99f6bd727 | ||
|
|
2faa2376a0 | ||
|
|
6f07409d7c | ||
|
|
b3145446aa | ||
|
|
2cc32db52d | ||
|
|
01d17dd5f9 | ||
|
|
c504fe4856 | ||
|
|
845ca8b34f | ||
|
|
6bd3d62d7c | ||
|
|
b89168d0f1 | ||
|
|
5adc661d05 | ||
|
|
44c466c0ea | ||
|
|
db2da43fc1 |
23
.gitignore
vendored
23
.gitignore
vendored
@@ -15,10 +15,21 @@ GPATH
|
||||
.#*
|
||||
\#*#
|
||||
|
||||
# Example project files
|
||||
examples/*/sdkconfig
|
||||
examples/*/sdkconfig.old
|
||||
examples/*/build
|
||||
# eclipse setting
|
||||
.settings
|
||||
|
||||
# Bootloader files
|
||||
components/bootloader/src/sdkconfig.old
|
||||
# Example project files
|
||||
examples/*/*/sdkconfig
|
||||
examples/*/*/sdkconfig.old
|
||||
examples/*/*/build
|
||||
|
||||
#Doc build artifacts
|
||||
docs/_build/
|
||||
docs/doxygen-warning-log.txt
|
||||
docs/xml/
|
||||
docs/man/
|
||||
|
||||
# Unit test app files
|
||||
tools/unit-test-app/sdkconfig
|
||||
tools/unit-test-app/sdkconfig.old
|
||||
tools/unit-test-app/build
|
||||
|
||||
542
.gitlab-ci.yml
542
.gitlab-ci.yml
@@ -1,6 +1,8 @@
|
||||
stages:
|
||||
- build
|
||||
- unit_test
|
||||
- test
|
||||
- test_report
|
||||
- deploy
|
||||
|
||||
before_script:
|
||||
@@ -12,9 +14,11 @@ before_script:
|
||||
- chmod 600 ~/.ssh/id_rsa
|
||||
- echo -e "Host gitlab.espressif.cn\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
|
||||
|
||||
# if testing master branch, use github wifi libs.
|
||||
# if testing other branches, use gitlab wifi libs (as maybe changes aren't merged to master yet)
|
||||
- test "${CI_BUILD_REF_NAME}" = "master" || sed -i "s%https://github.com/espressif/esp32-wifi-lib%ssh://git@gitlab.espressif.cn:27227/idf/esp32-wifi-lib%" .gitmodules
|
||||
# Set IS_PRIVATE or IS_PUBLIC depending on if our branch is public or not
|
||||
#
|
||||
# (the same regular expressions are used to set these are used in 'only:' sections below
|
||||
- source make/configure_ci_environment.sh
|
||||
|
||||
# fetch all submodules
|
||||
- git submodule update --init --recursive
|
||||
|
||||
@@ -28,6 +32,7 @@ build_template_app:
|
||||
SDK_PATH: "$CI_PROJECT_DIR"
|
||||
IDF_PATH: "$CI_PROJECT_DIR"
|
||||
GIT_STRATEGY: clone
|
||||
BATCH_BUILD: "1"
|
||||
|
||||
script:
|
||||
- git clone https://github.com/espressif/esp-idf-template.git
|
||||
@@ -36,8 +41,16 @@ build_template_app:
|
||||
# using on esp-idf. If it doesn't exist then just stick to the default
|
||||
# branch
|
||||
- git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..."
|
||||
- make defconfig
|
||||
# Test debug build (default)
|
||||
- make all V=1
|
||||
# Now test release build
|
||||
- make clean
|
||||
- sed -i.bak -e's/CONFIG_OPTIMIZATION_LEVEL_DEBUG\=y/CONFIG_OPTIMIZATION_LEVEL_RELEASE=y/' sdkconfig
|
||||
- make all V=1
|
||||
# Check if there are any stray printf/ets_printf references in WiFi libs
|
||||
- cd ../components/esp32/lib
|
||||
- test $(xtensa-esp32-elf-nm *.a | grep -w printf | wc -l) -eq 0
|
||||
- test $(xtensa-esp32-elf-nm *.a | grep -w ets_printf | wc -l) -eq 0
|
||||
|
||||
|
||||
.build_gitlab: &build_template
|
||||
@@ -50,25 +63,51 @@ build_template_app:
|
||||
SDK_PATH: "$CI_PROJECT_DIR"
|
||||
IDF_PATH: "$CI_PROJECT_DIR"
|
||||
GIT_STRATEGY: clone
|
||||
BATCH_BUILD: "1"
|
||||
|
||||
|
||||
build_ssc:
|
||||
<<: *build_template
|
||||
artifacts:
|
||||
paths:
|
||||
- ./SSC/build/*.bin
|
||||
- ./SSC/build/*.elf
|
||||
- ./SSC/build/*.map
|
||||
- ./SSC/build/bootloader/*.bin
|
||||
- ./SSC/ssc_bin
|
||||
expire_in: 6 mos
|
||||
|
||||
script:
|
||||
- git clone ssh://git@gitlab.espressif.cn:27227/yinling/SSC.git
|
||||
- git clone $GITLAB_SSH_SERVER/yinling/SSC.git
|
||||
- cd SSC
|
||||
- git checkout ${CI_BUILD_REF_NAME} || echo "Using SSC default branch..."
|
||||
- make defconfig
|
||||
- chmod +x gen_misc_ng.sh
|
||||
- ./gen_misc_ng.sh
|
||||
|
||||
build_at:
|
||||
<<: *build_template
|
||||
script:
|
||||
- git clone $GITLAB_SSH_SERVER/application/esp-at.git
|
||||
- cd esp-at
|
||||
- git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-at default branch..."
|
||||
- make defconfig
|
||||
- make
|
||||
|
||||
build_esp_idf_tests:
|
||||
<<: *build_template
|
||||
artifacts:
|
||||
paths:
|
||||
- ./tools/unit-test-app/build/*.bin
|
||||
- ./tools/unit-test-app/build/*.elf
|
||||
- ./tools/unit-test-app/build/*.map
|
||||
- ./tools/unit-test-app/build/bootloader/*.bin
|
||||
- ./components/idf_test/unit_test/TestCaseAll.yml
|
||||
- ./components/idf_test/unit_test/CIConfigs/*.yml
|
||||
expire_in: 6 mos
|
||||
|
||||
script:
|
||||
- cd tools/unit-test-app
|
||||
- git checkout ${CI_BUILD_REF_NAME} || echo "Using default branch..."
|
||||
- make TESTS_ALL=1
|
||||
- python UnitTestParser.py
|
||||
|
||||
build_examples:
|
||||
<<: *build_template
|
||||
artifacts:
|
||||
@@ -86,13 +125,31 @@ build_examples:
|
||||
- cd build_examples
|
||||
- ${IDF_PATH}/make/build_examples.sh
|
||||
|
||||
build_docs:
|
||||
stage: build
|
||||
image: espressif/esp32-ci-env
|
||||
tags:
|
||||
- build_docs
|
||||
script:
|
||||
- cd docs
|
||||
- doxygen
|
||||
# If not building master branch, and there are Doxygen warnings, print them and bail out
|
||||
- test -n $IS_PRIVATE && test $(cat doxygen-warning-log.txt | wc -l) -eq 0 || ( echo "Doxygen pass had some warnings:" && cat doxygen-warning-log.txt && false )
|
||||
- make gh-linkcheck
|
||||
- make html
|
||||
artifacts:
|
||||
paths:
|
||||
- docs/_build/html
|
||||
expire_in: 1 mos
|
||||
|
||||
|
||||
test_nvs_on_host:
|
||||
stage: test
|
||||
image: espressif/esp32-ci-env
|
||||
tags:
|
||||
- nvs_host_test
|
||||
script:
|
||||
- cd components/nvs_flash/test
|
||||
- cd components/nvs_flash/test_nvs_host
|
||||
- make test
|
||||
|
||||
test_build_system:
|
||||
@@ -103,59 +160,75 @@ test_build_system:
|
||||
variables:
|
||||
IDF_PATH: "$CI_PROJECT_DIR"
|
||||
script:
|
||||
- ./make/test_configure_ci_environment.sh
|
||||
- ./make/test_build_system.sh
|
||||
|
||||
|
||||
|
||||
# template for test jobs
|
||||
.test_template: &test_template
|
||||
stage: test
|
||||
when: on_success
|
||||
test_report:
|
||||
stage: test_report
|
||||
image: espressif/esp32-ci-env
|
||||
only:
|
||||
- master
|
||||
- triggers
|
||||
|
||||
- /^release\/v/
|
||||
- /^v\d+\.\d+(\.\d+)?($|-)/
|
||||
tags:
|
||||
- report
|
||||
variables:
|
||||
# need user to set SDK_NAME and CONFIG_FILE (may need to set BIN_PATH and APP_NAME later) in before_script
|
||||
SCRIPT_PATH: /home/gitlab-runner/auto_test_script
|
||||
BIN_PATH: ${CI_PROJECT_DIR}/SSC/build/
|
||||
APP_NAME: ssc
|
||||
LOG_PATH: $CI_PROJECT_DIR/$CI_BUILD_REF
|
||||
|
||||
LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF"
|
||||
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test"
|
||||
REPORT_PATH: "$CI_PROJECT_DIR/CI_Test_Report"
|
||||
MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/tools/unit-test-app/ModuleDefinition.yml"
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $REPORT_PATH
|
||||
- $LOG_PATH
|
||||
expire_in: 6 mos
|
||||
|
||||
expire_in: 12 mos
|
||||
script:
|
||||
- cd $SCRIPT_PATH
|
||||
- python CIRunner.py -l $LOG_PATH -c $SDK_NAME/$CONFIG_FILE bin_path $APP_NAME $BIN_PATH
|
||||
|
||||
sanity_test:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32
|
||||
- SSC_T1_1
|
||||
- SSC_T2_1
|
||||
- SSC_T1_WAN
|
||||
before_script:
|
||||
- SDK_NAME=ESP32_IDF
|
||||
- CONFIG_FILE=sanity_test.yml
|
||||
|
||||
# calc log path
|
||||
- VER_NUM=`git rev-list HEAD | wc -l | awk '{print $1}'`
|
||||
- SHA_ID=`echo $CI_BUILD_REF | cut -c 1-7`
|
||||
- REVISION="${VER_NUM}_${SHA_ID}"
|
||||
# replace / to _ in branch name
|
||||
- ESCAPED_BRANCH_NAME=`echo $CI_BUILD_REF_NAME | sed 's/\//___/g'`
|
||||
# result path and artifacts path
|
||||
- RESULT_PATH="$CI_PROJECT_NAME/$ESCAPED_BRANCH_NAME/$REVISION"
|
||||
- ARTIFACTS_PATH="$GITLAB_HTTP_SERVER/idf/esp-idf/builds/$CI_BUILD_ID/artifacts/browse/$CI_BUILD_REF"
|
||||
# clone test bench
|
||||
- git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git
|
||||
- cd auto_test_script
|
||||
# generate report
|
||||
- TEST_RESULT=Pass
|
||||
- python CITestReport.py -l $LOG_PATH -t $TEST_CASE_FILE_PATH -p $REPORT_PATH -r $RESULT_PATH -a $ARTIFACTS_PATH -m $MODULE_UPDATE_FILE || TEST_RESULT=Fail
|
||||
# commit to CI-test-result project
|
||||
- git clone $GITLAB_SSH_SERVER/qa/CI-test-result.git
|
||||
- rm -rf CI-test-result/RawData/$RESULT_PATH
|
||||
- cp -R $CI_PROJECT_NAME CI-test-result/RawData
|
||||
- cd CI-test-result
|
||||
# config git user
|
||||
- git config --global user.email "ci-test-result@espressif.com"
|
||||
- git config --global user.name "ci-test-result"
|
||||
# commit test result
|
||||
- git add .
|
||||
- git commit . -m "update test result for $CI_PROJECT_NAME/$CI_BUILD_REF_NAME/$CI_BUILD_REF, pipeline ID $CI_PIPELINE_ID" || exit 0
|
||||
- git push origin master
|
||||
- test "${TEST_RESULT}" = "Pass" || exit 1
|
||||
|
||||
push_master_to_github:
|
||||
before_script:
|
||||
before_script:
|
||||
- echo "Not setting up GitLab key, not fetching submodules"
|
||||
stage: deploy
|
||||
only:
|
||||
- master
|
||||
- /^release\/v/
|
||||
- /^v\d+\.\d+(\.\d+)?($|-)/
|
||||
tags:
|
||||
- deploy
|
||||
when: on_success
|
||||
image: espressif/esp32-ci-env
|
||||
variables:
|
||||
GIT_STRATEGY: clone
|
||||
GITHUB_PUSH_REFS: refs/remotes/origin/release refs/remotes/origin/master
|
||||
script:
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 700 ~/.ssh
|
||||
@@ -164,4 +237,391 @@ push_master_to_github:
|
||||
- chmod 600 ~/.ssh/id_rsa
|
||||
- echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
|
||||
- git remote add github git@github.com:espressif/esp-idf.git
|
||||
- git push github HEAD:master
|
||||
# What the next line of script does: goes through the list of refs for all branches we push to github,
|
||||
# generates a snippet of shell which is evaluated. The snippet checks CI_BUILD_REF against the SHA
|
||||
# (aka objectname) at tip of each branch, and if any SHAs match then it checks out the local branch
|
||||
# and then pushes that ref to a corresponding github branch
|
||||
#
|
||||
# NB: In gitlab 9.x, CI_BUILD_REF was deprecated. New name is CI_COMMIT_REF. If below command suddenly
|
||||
# generates bash syntax errors, this is probably why.
|
||||
- eval $(git for-each-ref --shell bash --format 'if [ $CI_BUILD_REF == %(objectname) ]; then git checkout -B %(refname:strip=3); git push --follow-tags github %(refname:strip=3); fi;' $GITHUB_PUSH_REFS)
|
||||
|
||||
|
||||
deploy_docs:
|
||||
before_script:
|
||||
- echo "Not setting up GitLab key, not fetching submodules"
|
||||
stage: deploy
|
||||
only:
|
||||
- master
|
||||
- /^release\/v/
|
||||
- /^v\d+\.\d+(\.\d+)?($|-)/
|
||||
- triggers
|
||||
tags:
|
||||
- deploy
|
||||
image: espressif/esp32-ci-env
|
||||
script:
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 700 ~/.ssh
|
||||
- echo -n $DOCS_DEPLOY_KEY > ~/.ssh/id_rsa_base64
|
||||
- base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa
|
||||
- chmod 600 ~/.ssh/id_rsa
|
||||
- echo -e "Host $DOCS_SERVER\n\tStrictHostKeyChecking no\n\tUser $DOCS_SERVER_USER\n" >> ~/.ssh/config
|
||||
- export GIT_VER=$(git describe --always)
|
||||
- cd docs/_build/
|
||||
- mv html $GIT_VER
|
||||
- tar czvf $GIT_VER.tar.gz $GIT_VER
|
||||
- scp $GIT_VER.tar.gz $DOCS_SERVER:$DOCS_PATH
|
||||
- ssh $DOCS_SERVER -x "cd $DOCS_PATH && tar xzvf $GIT_VER.tar.gz && rm -f latest && ln -s $GIT_VER latest"
|
||||
|
||||
check_doc_links:
|
||||
stage: test
|
||||
image: espressif/esp32-ci-env
|
||||
tags:
|
||||
- check_doc_links
|
||||
only:
|
||||
# can only be triggered
|
||||
- triggers
|
||||
script:
|
||||
# must be triggered with CHECK_LINKS=Yes, otherwise exit without test
|
||||
- test $CHECK_LINKS = "Yes" || exit 0
|
||||
# can only run on master branch (otherwise the commit is not on Github yet)
|
||||
- test "${CI_BUILD_REF_NAME}" = "master" || exit 0
|
||||
- cd docs
|
||||
- make linkcheck
|
||||
artifacts:
|
||||
paths:
|
||||
- docs/_build/linkcheck
|
||||
expire_in: 1 mos
|
||||
|
||||
|
||||
# AUTO GENERATED PART START, DO NOT MODIFY CONTENT BELOW
|
||||
# template for test jobs
|
||||
.test_template: &test_template
|
||||
stage: test
|
||||
when: on_success
|
||||
only:
|
||||
- master
|
||||
- /^release\/v/
|
||||
- /^v\d+\.\d+(\.\d+)?($|-)/
|
||||
- triggers
|
||||
allow_failure: true
|
||||
|
||||
variables:
|
||||
LOCAL_ENV_CONFIG_PATH: $CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32_IDF
|
||||
BIN_PATH: "$CI_PROJECT_DIR/SSC/ssc_bin/SSC"
|
||||
APP_NAME: "ssc"
|
||||
LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF"
|
||||
# append test level folder to TEST_CASE_FILE_PATH in before_script of test job
|
||||
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test/integration_test"
|
||||
# jobs MUST set CONFIG_FILE in before_script, and overwrite the variables above if necessary
|
||||
MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/components/idf_test/unit_test/ModuleDefinition.yml"
|
||||
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $LOG_PATH
|
||||
expire_in: 6 mos
|
||||
|
||||
script:
|
||||
# remove artifacts from last stage (UT logs)
|
||||
- rm -rf $LOG_PATH
|
||||
# add gitlab ssh key
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 700 ~/.ssh
|
||||
- echo -n $GITLAB_KEY > ~/.ssh/id_rsa_base64
|
||||
- base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa
|
||||
- chmod 600 ~/.ssh/id_rsa
|
||||
- echo -e "Host gitlab.espressif.cn\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
|
||||
# clone local test env configs
|
||||
- git clone $GITLAB_SSH_SERVER/qa/ci-test-runner-configs.git
|
||||
# clone test bench
|
||||
- git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git
|
||||
- cd auto_test_script
|
||||
# run test
|
||||
- python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH -m $MODULE_UPDATE_FILE bin_path $APP_NAME $BIN_PATH
|
||||
|
||||
|
||||
# template for overnight test jobs
|
||||
.test_template_night: &test_template_night
|
||||
<<: *test_template
|
||||
only:
|
||||
# can only be triggered
|
||||
- triggers
|
||||
script:
|
||||
# remove artifacts from last stage (UT logs)
|
||||
- rm -rf $LOG_PATH
|
||||
# must be night build triggers, otherwise exit without test
|
||||
- test $NIGHT_BUILD = "Yes" || exit 0
|
||||
# add gitlab ssh key
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 700 ~/.ssh
|
||||
- echo -n $GITLAB_KEY > ~/.ssh/id_rsa_base64
|
||||
- base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa
|
||||
- chmod 600 ~/.ssh/id_rsa
|
||||
- echo -e "Host gitlab.espressif.cn\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
|
||||
# clone local test env configs
|
||||
- git clone $GITLAB_SSH_SERVER/qa/ci-test-runner-configs.git
|
||||
# clone test bench
|
||||
- git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git
|
||||
- cd auto_test_script
|
||||
# run test
|
||||
- python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH -m $MODULE_UPDATE_FILE bin_path $APP_NAME $BIN_PATH
|
||||
|
||||
# template for unit test jobs
|
||||
.unit_test_template: &unit_test_template
|
||||
<<: *test_template
|
||||
allow_failure: false
|
||||
stage: unit_test
|
||||
|
||||
variables:
|
||||
LOCAL_ENV_CONFIG_PATH: $CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32_IDF
|
||||
BIN_PATH: "$CI_PROJECT_DIR/tools/unit-test-app/build/"
|
||||
LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF"
|
||||
APP_NAME: "ut"
|
||||
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test/unit_test"
|
||||
MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/tools/unit-test-app/ModuleDefinition.yml"
|
||||
|
||||
dependencies:
|
||||
- build_esp_idf_tests
|
||||
|
||||
UT_Function_SYS_01:
|
||||
<<: *unit_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/UT_Function_SYS_01.yml
|
||||
|
||||
UT_Function_SYS_02:
|
||||
<<: *unit_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/UT_Function_SYS_02.yml
|
||||
|
||||
IT_Function_SYS_01:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_SYS_01.yml
|
||||
|
||||
IT_Function_WIFI_01:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_01.yml
|
||||
|
||||
IT_Function_WIFI_02:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_02.yml
|
||||
|
||||
IT_Function_TCPIP_01:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_01.yml
|
||||
|
||||
IT_Function_TCPIP_02:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_02.yml
|
||||
|
||||
IT_Function_TCPIP_03:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_03.yml
|
||||
|
||||
IT_Function_TCPIP_04:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_04.yml
|
||||
|
||||
IT_Function_TCPIP_05:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_05.yml
|
||||
|
||||
IT_Stress_WIFI_01:
|
||||
<<: *test_template_night
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T5_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stress_WIFI_01.yml
|
||||
|
||||
IT_Stress_TCPIP_01:
|
||||
<<: *test_template_night
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stress_TCPIP_01.yml
|
||||
|
||||
IT_Stress_TCPIP_02:
|
||||
<<: *test_template_night
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stress_TCPIP_02.yml
|
||||
|
||||
IT_Stress_TCPIP_03:
|
||||
<<: *test_template_night
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stress_TCPIP_03.yml
|
||||
|
||||
IT_Stress_TCPIP_04:
|
||||
<<: *test_template_night
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stress_TCPIP_04.yml
|
||||
|
||||
IT_Stable_TCPIP_01:
|
||||
<<: *test_template_night
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T5_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stable_TCPIP_01.yml
|
||||
|
||||
IT_Stable_TCPIP_02:
|
||||
<<: *test_template_night
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stable_TCPIP_02.yml
|
||||
|
||||
IT_Stable_TCPIP_03:
|
||||
<<: *test_template_night
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T5_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Stable_TCPIP_03.yml
|
||||
|
||||
IT_Function_TCPIP_06:
|
||||
<<: *test_template_night
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_06.yml
|
||||
|
||||
IT_Function_WIFI_03:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_APC
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_03.yml
|
||||
|
||||
IT_Function_WIFI_04:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T3_PhyMode
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_04.yml
|
||||
|
||||
IT_Function_WIFI_05:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_WEP
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_05.yml
|
||||
|
||||
IT_Function_WIFI_06:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_PhyMode
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_06.yml
|
||||
|
||||
IT_Function_TCPIP_07:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T1_2
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_07.yml
|
||||
|
||||
IT_Function_TCPIP_08:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_08.yml
|
||||
|
||||
IT_Function_TCPIP_09:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T1_2
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_09.yml
|
||||
|
||||
IT_Function_TCPIP_10:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T1_2
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_10.yml
|
||||
|
||||
IT_Function_TCPIP_11:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_11.yml
|
||||
|
||||
IT_Function_TCPIP_12:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_12.yml
|
||||
|
||||
|
||||
8
.gitmodules
vendored
8
.gitmodules
vendored
@@ -3,7 +3,13 @@
|
||||
url = https://github.com/espressif/esp32-wifi-lib.git
|
||||
[submodule "components/esptool_py/esptool"]
|
||||
path = components/esptool_py/esptool
|
||||
url = https://github.com/themadinventor/esptool.git
|
||||
url = https://github.com/espressif/esptool.git
|
||||
[submodule "components/bt/lib"]
|
||||
path = components/bt/lib
|
||||
url = https://github.com/espressif/esp32-bt-lib.git
|
||||
[submodule "components/micro-ecc/micro-ecc"]
|
||||
path = components/micro-ecc/micro-ecc
|
||||
url = https://github.com/kmackay/micro-ecc.git
|
||||
[submodule "components/coap/libcoap"]
|
||||
path = components/coap/libcoap
|
||||
url = https://github.com/obgm/libcoap.git
|
||||
|
||||
@@ -1,30 +1,36 @@
|
||||
# Contributions Guide
|
||||
Contributions Guide
|
||||
===================
|
||||
|
||||
We welcome contributions to the esp-idf project!
|
||||
|
||||
## How to Contribute
|
||||
How to Contribute
|
||||
-----------------
|
||||
|
||||
Contributions to esp-idf - fixing bugs, adding features, adding documentation - are welcome. We accept contributions via [Github Pull Requests](https://help.github.com/articles/about-pull-requests/).
|
||||
Contributions to esp-idf - fixing bugs, adding features, adding documentation - are welcome. We accept contributions via `Github Pull Requests <https://help.github.com/articles/about-pull-requests/>`_.
|
||||
|
||||
## Before Contributing
|
||||
Before Contributing
|
||||
-------------------
|
||||
|
||||
Before sending us a Pull Request, please consider this list of points:
|
||||
|
||||
* Is the contribution entirely your own work, or already licensed under an Apache License 2.0 compatible Open Source License? If not then we unfortunately cannot accept it.
|
||||
|
||||
* Does any new code conform to the esp-idf Style Guide? (Style Guide currently pending).
|
||||
* Does any new code conform to the esp-idf :doc:`Style Guide <style-guide>`?
|
||||
|
||||
* Does the code documentation follow requirements in :doc:`documenting-code`?
|
||||
|
||||
* Is the code adequately commented for people to understand how it is structured?
|
||||
|
||||
* Is there documentation or examples that go with code contributions? [There are additional suggestions for writing good examples in the examples README](examples/README.md).
|
||||
* Is there documentation or examples that go with code contributions? There are additional suggestions for writing good examples in :idf:`examples` readme.
|
||||
|
||||
* Are comments and documentation written in clear English, with no spelling or grammar errors?
|
||||
|
||||
* If the contribution contains multiple commits, are they grouped together into logical changes (one major change per pull request)? Are any commits with names like "fixed typo" [squashed into previous commits](http://eli.thegreenplace.net/2014/02/19/squashing-github-pull-requests-into-a-single-commit/)?
|
||||
* If the contribution contains multiple commits, are they grouped together into logical changes (one major change per pull request)? Are any commits with names like "fixed typo" `squashed into previous commits <http://eli.thegreenplace.net/2014/02/19/squashing-github-pull-requests-into-a-single-commit/>`_?
|
||||
|
||||
* If you're unsure about any of these points, please open the Pull Request anyhow and then ask us for feedback.
|
||||
|
||||
## Pull Request Process
|
||||
Pull Request Process
|
||||
--------------------
|
||||
|
||||
After you open the Pull Request, there will probably be some discussion in the comments field of the request itself.
|
||||
|
||||
@@ -32,6 +38,10 @@ Once the Pull Request is ready to merge, it will first be merged into our intern
|
||||
|
||||
If this process passes, it will be merged onto the public github repository.
|
||||
|
||||
## Legal Part
|
||||
Legal Part
|
||||
----------
|
||||
|
||||
Before a contribution can be accepted, you will need to sign our :doc:`contributor-agreement`. You will be prompted for this automatically as part of the Pull Request process.
|
||||
|
||||
|
||||
|
||||
Before a contribution can be accepted, you will need to sign our [Contributor Agreement](docs/contributor-agreement.rst). You will be prompted for this automatically as part of the Pull Request process.
|
||||
20
Kconfig
20
Kconfig
@@ -23,6 +23,26 @@ endmenu
|
||||
|
||||
source "$COMPONENT_KCONFIGS_PROJBUILD"
|
||||
|
||||
choice OPTIMIZATION_LEVEL
|
||||
prompt "Optimization level"
|
||||
default OPTIMIZATION_LEVEL_DEBUG
|
||||
help
|
||||
This option sets optimization level.
|
||||
|
||||
- for "Release" setting, -Os flag is added to CFLAGS,
|
||||
and -DNDEBUG flag is added to CPPFLAGS.
|
||||
|
||||
- for "Debug" setting, -Og flag is added to CFLAGS.
|
||||
|
||||
To override any of these settings, set CFLAGS and/or CPPFLAGS
|
||||
in project makefile, before including $(IDF_PATH)/make/project.mk.
|
||||
|
||||
config OPTIMIZATION_LEVEL_DEBUG
|
||||
bool "Debug"
|
||||
config OPTIMIZATION_LEVEL_RELEASE
|
||||
bool "Release"
|
||||
endchoice
|
||||
|
||||
menu "Component config"
|
||||
source "$COMPONENT_KCONFIGS"
|
||||
endmenu
|
||||
|
||||
79
README.md
79
README.md
@@ -1,30 +1,46 @@
|
||||
# Using Espressif IoT Development Framework with the ESP32
|
||||
# Espressif IoT Development Framework
|
||||
|
||||
# Setting Up ESP-IDF
|
||||
[](http://esp-idf.readthedocs.io/en/latest/?badge=latest)
|
||||
|
||||
In the [docs](docs) directory you will find per-platform setup guides:
|
||||
ESP-IDF is the official development framework for the [ESP32](https://espressif.com/en/products/hardware/esp32/overview>) chip.
|
||||
|
||||
* [Windows Setup Guide](docs/windows-setup.rst)
|
||||
* [Mac OS Setup Guide](docs/macos-setup.rst)
|
||||
* [Linux Setup Guide](docs/linux-setup.rst)
|
||||
# Developing With the ESP-IDF
|
||||
|
||||
# Finding A Project
|
||||
## Setting Up ESP-IDF
|
||||
|
||||
As well as the [esp-idf-template](https://github.com/espressif/esp-idf-template) project mentioned in the setup guide, esp-idf comes with some example projects in the [examples](examples) directory.
|
||||
See setup guides for detailed instructions to set up the ESP-IDF:
|
||||
|
||||
Once you've found the project you want to work with, change to its directory and you can configure and build it:
|
||||
* [Windows Setup Guide](http://esp-idf.readthedocs.io/en/latest/windows-setup.html)
|
||||
* [Mac OS Setup Guide](http://esp-idf.readthedocs.io/en/latest/macos-setup.html)
|
||||
* [Linux Setup Guide](http://esp-idf.readthedocs.io/en/latest/linux-setup.html)
|
||||
|
||||
# Configuring your project
|
||||
## Finding a Project
|
||||
|
||||
As well as the [esp-idf-template](https://github.com/espressif/esp-idf-template) project mentioned in the setup guide, ESP-IDF comes with some example projects in the [examples](examples) directory.
|
||||
|
||||
Once you've found the project you want to work with, change to its directory and you can configure and build it.
|
||||
|
||||
## Configuring the Project
|
||||
|
||||
`make menuconfig`
|
||||
|
||||
# Compiling your project
|
||||
* Opens a text-based configuration menu for the project.
|
||||
* Use up & down arrow keys to navigate the menu.
|
||||
* Use Enter key to go into a submenu, Escape key to go out or to exit.
|
||||
* Type `?` to see a help screen. Enter key exits the help screen.
|
||||
* Use Space key, or `Y` and `N` keys to enable (Yes) and disable (No) configuration items with checkboxes "`[*]`"
|
||||
* Pressing `?` while highlighting a configuration item displays help about that item.
|
||||
* Type `/` to search the configuration items.
|
||||
|
||||
Once done configuring, press Escape multiple times to exit and say "Yes" to save the new configuration when prompted.
|
||||
|
||||
## Compiling the Project
|
||||
|
||||
`make all`
|
||||
|
||||
... will compile app, bootloader and generate a partition table based on the config.
|
||||
|
||||
# Flashing your project
|
||||
## Flashing the Project
|
||||
|
||||
When `make all` finishes, it will print a command line to use esptool.py to flash the chip. However you can also do this from make by running:
|
||||
|
||||
@@ -34,7 +50,17 @@ This will flash the entire project (app, bootloader and partition table) to a ne
|
||||
|
||||
You don't need to run `make all` before running `make flash`, `make flash` will automatically rebuild anything which needs it.
|
||||
|
||||
# Compiling & Flashing Just the App
|
||||
## Viewing Serial Output
|
||||
|
||||
The `make monitor` target will use the already-installed [miniterm](http://pyserial.readthedocs.io/en/latest/tools.html#module-serial.tools.miniterm) (a part of pyserial) to display serial output from the ESP32 on the terminal console.
|
||||
|
||||
Exit miniterm by typing Ctrl-].
|
||||
|
||||
To flash and monitor output in one pass, you can run:
|
||||
|
||||
`make flash monitor`
|
||||
|
||||
## Compiling & Flashing Just the App
|
||||
|
||||
After the initial flash, you may just want to build and flash just your app, not the bootloader and partition table:
|
||||
|
||||
@@ -43,9 +69,19 @@ After the initial flash, you may just want to build and flash just your app, not
|
||||
|
||||
`make app-flash` will automatically rebuild the app if it needs it.
|
||||
|
||||
(There's no downside to reflashing the bootloader and partition table each time, if they haven't changed.)
|
||||
(In normal development there's no downside to reflashing the bootloader and partition table each time, if they haven't changed.)
|
||||
|
||||
# The Partition Table
|
||||
## Parallel Builds
|
||||
|
||||
ESP-IDF supports compiling multiple files in parallel, so all of the above commands can be run as `make -jN` where `N` is the number of parallel make processes to run (generally N should be equal to or one more than the number of CPU cores in your system.)
|
||||
|
||||
Multiple make functions can be combined into one. For example: to build the app & bootloader using 5 jobs in parallel, then flash everything, and then display serial output from the ESP32 run:
|
||||
|
||||
```
|
||||
make -j5 flash monitor
|
||||
```
|
||||
|
||||
## The Partition Table
|
||||
|
||||
Once you've compiled your project, the "build" directory will contain a binary file with a name like "my_app.bin". This is an ESP32 image binary that can be loaded by the bootloader.
|
||||
|
||||
@@ -60,14 +96,21 @@ The simplest way to use the partition table is to `make menuconfig` and choose o
|
||||
|
||||
In both cases the factory app is flashed at offset 0x10000. If you `make partition_table` then it will print a summary of the partition table.
|
||||
|
||||
For more details about partition tables and how to create custom variations, view the `docs/partition_tables.rst` file.
|
||||
For more details about partition tables and how to create custom variations, view the `docs/partition-tables.rst` file.
|
||||
|
||||
## Erasing Flash
|
||||
|
||||
The `make flash` target does not erase the entire flash contents. However it is sometimes useful to set the device back to a totally erased state, particularly when making partition table changes or OTA app updates. To erase the entire flash, run `make erase_flash`.
|
||||
|
||||
This can be combined with other targets, ie `make erase_flash flash` will erase everything and then re-flash the new app, bootloader and partition table.
|
||||
|
||||
# Resources
|
||||
|
||||
* The [docs directory of the esp-idf repository](docs) contains esp-idf documentation.
|
||||
* Documentation for the latest version: http://esp-idf.readthedocs.io/. This documentation is built from the [docs directory](docs) of this repository.
|
||||
|
||||
* The [esp32.com forum](http://esp32.com/) is a place to ask questions and find community resources.
|
||||
|
||||
* [Check the Issues section on github](https://github.com/espressif/esp-idf/issues) if you find a bug or have a feature request. Please check existing Issues before opening a new one.
|
||||
|
||||
* If you're interested in contributing to esp-idf, please check the [CONTRIBUTING.md](CONTRIBUTING.md) file.
|
||||
* If you're interested in contributing to ESP-IDF, please check the [Contributions Guide](http://esp-idf.readthedocs.io/en/latest/contributing.html>).
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
if [ -z ${IDF_PATH} ]; then
|
||||
echo "IDF_PATH must be set before including this script."
|
||||
else
|
||||
IDF_ADD_PATHS_EXTRAS="${IDF_PATH}/components/esptool_py/esptool:${IDF_PATH}/components/partition_table/"
|
||||
IDF_ADD_PATHS_EXTRAS="${IDF_PATH}/components/esptool_py/esptool:${IDF_PATH}/components/espcoredump:${IDF_PATH}/components/partition_table/"
|
||||
export PATH="${PATH}:${IDF_ADD_PATHS_EXTRAS}"
|
||||
echo "Added to PATH: ${IDF_ADD_PATHS_EXTRAS}"
|
||||
fi
|
||||
|
||||
5
components/app_update/component.mk
Executable file
5
components/app_update/component.mk
Executable file
@@ -0,0 +1,5 @@
|
||||
#
|
||||
# Component Makefile
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
|
||||
448
components/app_update/esp_ota_ops.c
Normal file
448
components/app_update/esp_ota_ops.c
Normal file
@@ -0,0 +1,448 @@
|
||||
// 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 <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_partition.h"
|
||||
#include "esp_spi_flash.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "esp_ota_ops.h"
|
||||
#include "rom/queue.h"
|
||||
#include "rom/crc.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
|
||||
#define OTA_MAX(a,b) ((a) >= (b) ? (a) : (b))
|
||||
#define OTA_MIN(a,b) ((a) <= (b) ? (a) : (b))
|
||||
#define SUB_TYPE_ID(i) (i & 0x0F)
|
||||
|
||||
typedef struct ota_ops_entry_ {
|
||||
uint32_t handle;
|
||||
esp_partition_t part;
|
||||
uint32_t erased_size;
|
||||
uint32_t wrote_size;
|
||||
#ifdef CONFIG_FLASH_ENCRYPTION_ENABLED
|
||||
uint8_t partial_bytes;
|
||||
uint8_t partial_data[16];
|
||||
#endif
|
||||
LIST_ENTRY(ota_ops_entry_) entries;
|
||||
} ota_ops_entry_t;
|
||||
|
||||
/* OTA selection structure (two copies in the OTA data partition.)
|
||||
Size of 32 bytes is friendly to flash encryption */
|
||||
typedef struct {
|
||||
uint32_t ota_seq;
|
||||
uint8_t seq_label[24];
|
||||
uint32_t crc; /* CRC32 of ota_seq field only */
|
||||
} ota_select;
|
||||
|
||||
static LIST_HEAD(ota_ops_entries_head, ota_ops_entry_) s_ota_ops_entries_head =
|
||||
LIST_HEAD_INITIALIZER(s_ota_ops_entries_head);
|
||||
|
||||
static uint32_t s_ota_ops_last_handle = 0;
|
||||
static ota_select s_ota_select[2];
|
||||
|
||||
const static char *TAG = "esp_ota_ops";
|
||||
|
||||
esp_err_t esp_ota_begin(const esp_partition_t *partition, size_t image_size, esp_ota_handle_t *out_handle)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if ((partition == NULL) || (out_handle == NULL)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ota_ops_entry_t *new_entry = (ota_ops_entry_t *) calloc(sizeof(ota_ops_entry_t), 1);
|
||||
|
||||
if (new_entry == 0) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
// if input image size is 0 or OTA_SIZE_UNKNOWN, will erase all areas in this partition
|
||||
if ((image_size == 0) || (image_size == OTA_SIZE_UNKNOWN)) {
|
||||
ret = esp_partition_erase_range(partition, 0, partition->size);
|
||||
} else {
|
||||
ret = esp_partition_erase_range(partition, 0, (image_size / SPI_FLASH_SEC_SIZE + 1) * SPI_FLASH_SEC_SIZE);
|
||||
}
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
free(new_entry);
|
||||
new_entry = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
LIST_INSERT_HEAD(&s_ota_ops_entries_head, new_entry, entries);
|
||||
|
||||
if ((image_size == 0) || (image_size == OTA_SIZE_UNKNOWN)) {
|
||||
new_entry->erased_size = partition->size;
|
||||
} else {
|
||||
new_entry->erased_size = image_size;
|
||||
}
|
||||
|
||||
memcpy(&new_entry->part, partition, sizeof(esp_partition_t));
|
||||
new_entry->handle = ++s_ota_ops_last_handle;
|
||||
*out_handle = new_entry->handle;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size)
|
||||
{
|
||||
const uint8_t *data_bytes = (const uint8_t *)data;
|
||||
esp_err_t ret;
|
||||
ota_ops_entry_t *it;
|
||||
|
||||
if (data == NULL) {
|
||||
ESP_LOGE(TAG, "write data is invalid");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
// find ota handle in linked list
|
||||
for (it = LIST_FIRST(&s_ota_ops_entries_head); it != NULL; it = LIST_NEXT(it, entries)) {
|
||||
if (it->handle == handle) {
|
||||
// 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 && size > 0 && data_bytes[0] != 0xE9) {
|
||||
ESP_LOGE(TAG, "OTA image has invalid magic byte (expected 0xE9, saw 0x%02x", data_bytes[0]);
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FLASH_ENCRYPTION_ENABLED
|
||||
if (esp_flash_encryption_enabled()) {
|
||||
/* Can only write 16 byte blocks to flash, so need to cache anything else */
|
||||
size_t copy_len;
|
||||
|
||||
/* check if we have partially written data from earlier */
|
||||
if (it->partial_bytes != 0) {
|
||||
copy_len = OTA_MIN(16 - it->partial_bytes, size);
|
||||
memcpy(it->partial_data + it->partial_bytes, data_bytes, copy_len);
|
||||
it->partial_bytes += copy_len;
|
||||
if (it->partial_bytes != 16) {
|
||||
return ESP_OK; /* nothing to write yet, just filling buffer */
|
||||
}
|
||||
/* write 16 byte to partition */
|
||||
ret = esp_partition_write(&it->part, it->wrote_size, it->partial_data, 16);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
it->partial_bytes = 0;
|
||||
memset(it->partial_data, 0xFF, 16);
|
||||
it->wrote_size += 16;
|
||||
data_bytes += copy_len;
|
||||
size -= copy_len;
|
||||
}
|
||||
|
||||
/* check if we need to save trailing data that we're about to write */
|
||||
it->partial_bytes = size % 16;
|
||||
if (it->partial_bytes != 0) {
|
||||
size -= it->partial_bytes;
|
||||
memcpy(it->partial_data, data_bytes + size, it->partial_bytes);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = esp_partition_write(&it->part, it->wrote_size, data_bytes, size);
|
||||
if(ret == ESP_OK){
|
||||
it->wrote_size += size;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
//if go to here ,means don't find the handle
|
||||
ESP_LOGE(TAG,"not found the handle")
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_end(esp_ota_handle_t handle)
|
||||
{
|
||||
ota_ops_entry_t *it;
|
||||
size_t image_size;
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
for (it = LIST_FIRST(&s_ota_ops_entries_head); it != NULL; it = LIST_NEXT(it, entries)) {
|
||||
if (it->handle == handle) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (it == NULL) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* 'it' holds the ota_ops_entry_t for 'handle' */
|
||||
|
||||
// esp_ota_end() is only valid if some data was written to this handle
|
||||
if ((it->erased_size == 0) || (it->wrote_size == 0)) {
|
||||
ret = ESP_ERR_INVALID_ARG;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FLASH_ENCRYPTION_ENABLED
|
||||
if (it->partial_bytes > 0 && esp_flash_encryption_enabled()) {
|
||||
/* Write out last 16 bytes, if necessary */
|
||||
ret = esp_partition_write(&it->part, it->wrote_size, it->partial_data, 16);
|
||||
if (ret != ESP_OK) {
|
||||
ret = ESP_ERR_INVALID_STATE;
|
||||
goto cleanup;
|
||||
}
|
||||
it->wrote_size += 16;
|
||||
it->partial_bytes = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (esp_image_basic_verify(it->part.address, true, &image_size) != ESP_OK) {
|
||||
ret = ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
ret = esp_secure_boot_verify_signature(it->part.address, image_size);
|
||||
if (ret != ESP_OK) {
|
||||
ret = ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
goto cleanup;
|
||||
}
|
||||
#endif
|
||||
|
||||
cleanup:
|
||||
LIST_REMOVE(it, entries);
|
||||
free(it);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint32_t ota_select_crc(const ota_select *s)
|
||||
{
|
||||
return crc32_le(UINT32_MAX, (uint8_t *)&s->ota_seq, 4);
|
||||
}
|
||||
|
||||
static bool ota_select_valid(const ota_select *s)
|
||||
{
|
||||
return s->ota_seq != UINT32_MAX && s->crc == ota_select_crc(s);
|
||||
}
|
||||
|
||||
static esp_err_t rewrite_ota_seq(uint32_t seq, uint8_t sec_id, const esp_partition_t *ota_data_partition)
|
||||
{
|
||||
esp_err_t ret;
|
||||
|
||||
if (sec_id == 0 || sec_id == 1) {
|
||||
s_ota_select[sec_id].ota_seq = seq;
|
||||
s_ota_select[sec_id].crc = ota_select_crc(&s_ota_select[sec_id]);
|
||||
ret = esp_partition_erase_range(ota_data_partition, sec_id * SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
} else {
|
||||
return esp_partition_write(ota_data_partition, SPI_FLASH_SEC_SIZE * sec_id, &s_ota_select[sec_id].ota_seq, sizeof(ota_select));
|
||||
}
|
||||
} else {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t get_ota_partition_count(void)
|
||||
{
|
||||
uint16_t ota_app_count = 0;
|
||||
while (esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ota_app_count, NULL) != NULL) {
|
||||
assert(ota_app_count < 16 && "must erase the partition before writing to it");
|
||||
ota_app_count++;
|
||||
}
|
||||
return ota_app_count;
|
||||
}
|
||||
|
||||
static esp_err_t esp_rewrite_ota_data(esp_partition_subtype_t subtype)
|
||||
{
|
||||
esp_err_t ret;
|
||||
const esp_partition_t *find_partition = NULL;
|
||||
uint16_t ota_app_count = 0;
|
||||
uint32_t i = 0;
|
||||
uint32_t seq;
|
||||
static spi_flash_mmap_memory_t ota_data_map;
|
||||
const void *result = NULL;
|
||||
|
||||
find_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
if (find_partition != NULL) {
|
||||
ota_app_count = get_ota_partition_count();
|
||||
//esp32_idf use two sector for store information about which partition is running
|
||||
//it defined the two sector as ota data partition,two structure ota_select is saved in the two sector
|
||||
//named data in first sector as s_ota_select[0], second sector data as s_ota_select[1]
|
||||
//e.g.
|
||||
//if s_ota_select[0].ota_seq == s_ota_select[1].ota_seq == 0xFFFFFFFF,means ota info partition is in init status
|
||||
//so it will boot factory application(if there is),if there's no factory application,it will boot ota[0] application
|
||||
//if s_ota_select[0].ota_seq != 0 and s_ota_select[1].ota_seq != 0,it will choose a max seq ,and get value of max_seq%max_ota_app_number
|
||||
//and boot a subtype (mask 0x0F) value is (max_seq - 1)%max_ota_app_number,so if want switch to run ota[x],can use next formulas.
|
||||
//for example, if s_ota_select[0].ota_seq = 4, s_ota_select[1].ota_seq = 5, and there are 8 ota application,
|
||||
//current running is (5-1)%8 = 4,running ota[4],so if we want to switch to run ota[7],
|
||||
//we should add s_ota_select[0].ota_seq (is 4) to 4 ,(8-1)%8=7,then it will boot ota[7]
|
||||
//if A=(B - C)%D
|
||||
//then B=(A + C)%D + D*n ,n= (0,1,2...)
|
||||
//so current ota app sub type id is x , dest bin subtype is y,total ota app count is n
|
||||
//seq will add (x + n*1 + 1 - seq)%n
|
||||
if (SUB_TYPE_ID(subtype) >= ota_app_count) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
ret = esp_partition_mmap(find_partition, 0, find_partition->size, SPI_FLASH_MMAP_DATA, &result, &ota_data_map);
|
||||
if (ret != ESP_OK) {
|
||||
result = NULL;
|
||||
return ret;
|
||||
} else {
|
||||
memcpy(&s_ota_select[0], result, sizeof(ota_select));
|
||||
memcpy(&s_ota_select[1], result + SPI_FLASH_SEC_SIZE, sizeof(ota_select));
|
||||
spi_flash_munmap(ota_data_map);
|
||||
}
|
||||
|
||||
if (ota_select_valid(&s_ota_select[0]) && ota_select_valid(&s_ota_select[1])) {
|
||||
seq = OTA_MAX(s_ota_select[0].ota_seq, s_ota_select[1].ota_seq);
|
||||
while (seq > (SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count) {
|
||||
i++;
|
||||
}
|
||||
|
||||
if (s_ota_select[0].ota_seq >= s_ota_select[1].ota_seq) {
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 0, find_partition);
|
||||
} else {
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 1, find_partition);
|
||||
}
|
||||
|
||||
} else if (ota_select_valid(&s_ota_select[0])) {
|
||||
while (s_ota_select[0].ota_seq > (SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count) {
|
||||
i++;
|
||||
}
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 1, find_partition);
|
||||
|
||||
} else if (ota_select_valid(&s_ota_select[1])) {
|
||||
while (s_ota_select[1].ota_seq > (SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count) {
|
||||
i++;
|
||||
}
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 0, find_partition);
|
||||
|
||||
} else {
|
||||
/* Both OTA slots are invalid, probably because unformatted... */
|
||||
return rewrite_ota_seq(SUB_TYPE_ID(subtype) + 1, 0, find_partition);
|
||||
}
|
||||
|
||||
} else {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_set_boot_partition(const esp_partition_t *partition)
|
||||
{
|
||||
size_t image_size;
|
||||
const esp_partition_t *find_partition = NULL;
|
||||
if (partition == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (esp_image_basic_verify(partition->address, true, &image_size) != ESP_OK) {
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
esp_err_t ret = esp_secure_boot_verify_signature(partition->address, image_size);
|
||||
if (ret != ESP_OK) {
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
#endif
|
||||
// if set boot partition to factory bin ,just format ota info partition
|
||||
if (partition->type == ESP_PARTITION_TYPE_APP) {
|
||||
if (partition->subtype == ESP_PARTITION_SUBTYPE_APP_FACTORY) {
|
||||
find_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
if (find_partition != NULL) {
|
||||
return esp_partition_erase_range(find_partition, 0, find_partition->size);
|
||||
} else {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
} else {
|
||||
// try to find this partition in flash,if not find it ,return error
|
||||
find_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
if (find_partition != NULL) {
|
||||
return esp_rewrite_ota_data(partition->subtype);
|
||||
} else {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
const esp_partition_t *esp_ota_get_boot_partition(void)
|
||||
{
|
||||
esp_err_t ret;
|
||||
const esp_partition_t *find_partition = NULL;
|
||||
static spi_flash_mmap_memory_t ota_data_map;
|
||||
const void *result = NULL;
|
||||
uint16_t ota_app_count = 0;
|
||||
find_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
|
||||
if (find_partition == NULL) {
|
||||
ESP_LOGE(TAG, "not found ota data");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = esp_partition_mmap(find_partition, 0, find_partition->size, SPI_FLASH_MMAP_DATA, &result, &ota_data_map);
|
||||
if (ret != ESP_OK) {
|
||||
spi_flash_munmap(ota_data_map);
|
||||
ESP_LOGE(TAG, "mmap ota data filed");
|
||||
return NULL;
|
||||
} else {
|
||||
memcpy(&s_ota_select[0], result, sizeof(ota_select));
|
||||
memcpy(&s_ota_select[1], result + 0x1000, sizeof(ota_select));
|
||||
spi_flash_munmap(ota_data_map);
|
||||
}
|
||||
ota_app_count = get_ota_partition_count();
|
||||
|
||||
ESP_LOGD(TAG, "found ota app max = %d", ota_app_count);
|
||||
|
||||
if (s_ota_select[0].ota_seq == 0xFFFFFFFF && s_ota_select[1].ota_seq == 0xFFFFFFFF) {
|
||||
ESP_LOGD(TAG, "finding factory app......");
|
||||
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);
|
||||
} else if (ota_select_valid(&s_ota_select[0]) && ota_select_valid(&s_ota_select[1])) {
|
||||
ESP_LOGD(TAG, "finding ota_%d app......", \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ((OTA_MAX(s_ota_select[0].ota_seq, s_ota_select[1].ota_seq) - 1) % ota_app_count));
|
||||
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ((OTA_MAX(s_ota_select[0].ota_seq, s_ota_select[1].ota_seq) - 1) % ota_app_count), NULL);
|
||||
} else if (ota_select_valid(&s_ota_select[0])) {
|
||||
ESP_LOGD(TAG, "finding ota_%d app......", \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[0].ota_seq - 1) % ota_app_count);
|
||||
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[0].ota_seq - 1) % ota_app_count, NULL);
|
||||
|
||||
} else if (ota_select_valid(&s_ota_select[1])) {
|
||||
ESP_LOGD(TAG, "finding ota_%d app......", \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[1].ota_seq - 1) % ota_app_count);
|
||||
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[1].ota_seq - 1) % ota_app_count, NULL);
|
||||
|
||||
} else {
|
||||
ESP_LOGE(TAG, "ota data invalid, no current app. Assuming factory");
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);
|
||||
}
|
||||
}
|
||||
115
components/app_update/include/esp_ota_ops.h
Executable file
115
components/app_update/include/esp_ota_ops.h
Executable file
@@ -0,0 +1,115 @@
|
||||
// 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 _OTA_OPS_H
|
||||
#define _OTA_OPS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_partition.h"
|
||||
#include "esp_spi_flash.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define OTA_SIZE_UNKNOWN 0xffffffff
|
||||
|
||||
#define ESP_ERR_OTA_BASE 0x1500 /*!< base error code for ota_ops api */
|
||||
#define ESP_ERR_OTA_PARTITION_CONFLICT (ESP_ERR_OTA_BASE + 0x01) /*!< want to write or erase current running partition */
|
||||
#define ESP_ERR_OTA_SELECT_INFO_INVALID (ESP_ERR_OTA_BASE + 0x02) /*!< ota data partition info is error */
|
||||
#define ESP_ERR_OTA_VALIDATE_FAILED (ESP_ERR_OTA_BASE + 0x03) /*!< validate ota image failed */
|
||||
|
||||
/**
|
||||
* @brief Opaque handle for application update obtained from app_ops.
|
||||
*/
|
||||
typedef uint32_t esp_ota_handle_t;
|
||||
|
||||
/**
|
||||
* @brief format input partition in flash to 0xFF as input image size,
|
||||
* if unkown image size ,pass 0x0 or 0xFFFFFFFF, it will erase all the
|
||||
* partition ,Otherwise, erase the required range
|
||||
*
|
||||
* @param partition Pointer to partition structure which need to be updated
|
||||
* Must be non-NULL.
|
||||
* @param image_size size of image need to be updated
|
||||
* @param out_handle handle which should be used for esp_ota_write or esp_ota_end call
|
||||
|
||||
* @return:
|
||||
* - ESP_OK: if format ota image OK
|
||||
* - ESP_ERR_OTA_PARTITION_CONFLICT: operate current running bin
|
||||
* - ESP_ERR_OTA_SELECT_INFO_INVALID: ota bin select info invalid
|
||||
*/
|
||||
esp_err_t esp_ota_begin(const esp_partition_t* partition, size_t image_size, esp_ota_handle_t* out_handle);
|
||||
|
||||
/**
|
||||
* @brief Write data to input input partition
|
||||
*
|
||||
* @param handle Handle obtained from esp_ota_begin
|
||||
* @param data Pointer to data write to flash
|
||||
* @param size data size of recieved data
|
||||
*
|
||||
* @return:
|
||||
* - ESP_OK: if write flash data OK
|
||||
* - ESP_ERR_OTA_PARTITION_CONFLICT: operate current running bin
|
||||
* - ESP_ERR_OTA_SELECT_INFO_INVALID: ota bin select info invalid
|
||||
*/
|
||||
esp_err_t esp_ota_write(esp_ota_handle_t handle, const void* data, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Finish the update and validate written data
|
||||
*
|
||||
* @param handle Handle obtained from esp_ota_begin.
|
||||
*
|
||||
* @note After calling esp_ota_end(), the handle is no longer valid and any memory associated with it is freed (regardless of result).
|
||||
*
|
||||
* @return:
|
||||
* - ESP_OK: Newly written OTA app image is valid.
|
||||
* - ESP_ERR_NOT_FOUND: OTA handle was not found.
|
||||
* - ESP_ERR_INVALID_ARG: Handle was never written to.
|
||||
* - ESP_ERR_OTA_VALIDATE_FAILED: OTA image is invalid (either not a valid app image, or - if secure boot is enabled - signature failed to verify.)
|
||||
* - ESP_ERR_INVALID_STATE: If flash encryption is enabled, this result indicates an internal error writing the final encrypted bytes to flash.
|
||||
*/
|
||||
esp_err_t esp_ota_end(esp_ota_handle_t handle);
|
||||
|
||||
/**
|
||||
* @brief Set next boot partition, call system_restart() will switch to run it
|
||||
*
|
||||
* @note if you want switch to run a bin file
|
||||
* has never been checked before,please validate it's signature firstly
|
||||
*
|
||||
* @param partition Pointer to partition structure which need to boot
|
||||
*
|
||||
* @return:
|
||||
* - ESP_OK: if set next boot partition OK
|
||||
* - ESP_ERR_OTA_SELECT_INFO_INVALID: ota bin select info invalid
|
||||
*/
|
||||
esp_err_t esp_ota_set_boot_partition(const esp_partition_t* partition);
|
||||
|
||||
/**
|
||||
* @brief Get partition info of current running image
|
||||
*
|
||||
* @return pointer to esp_partition_t structure, or NULL if no partition is found or
|
||||
* operate flash failed,This pointer is valid for the lifetime of the application.
|
||||
*/
|
||||
const esp_partition_t* esp_ota_get_boot_partition(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OTA_OPS_H */
|
||||
@@ -1,7 +1,7 @@
|
||||
menu "Bootloader config"
|
||||
choice LOG_BOOTLOADER_LEVEL
|
||||
bool "Bootloader log verbosity"
|
||||
default LOG_BOOTLOADER_LEVEL_WARN
|
||||
default LOG_BOOTLOADER_LEVEL_INFO
|
||||
help
|
||||
Specify how much output to see in bootloader logs.
|
||||
|
||||
@@ -20,12 +20,198 @@ config LOG_BOOTLOADER_LEVEL_VERBOSE
|
||||
endchoice
|
||||
|
||||
config LOG_BOOTLOADER_LEVEL
|
||||
int
|
||||
default 0 if LOG_BOOTLOADER_LEVEL_NONE
|
||||
default 1 if LOG_BOOTLOADER_LEVEL_ERROR
|
||||
default 2 if LOG_BOOTLOADER_LEVEL_WARN
|
||||
default 3 if LOG_BOOTLOADER_LEVEL_INFO
|
||||
default 4 if LOG_BOOTLOADER_LEVEL_DEBUG
|
||||
default 5 if LOG_BOOTLOADER_LEVEL_VERBOSE
|
||||
int
|
||||
default 0 if LOG_BOOTLOADER_LEVEL_NONE
|
||||
default 1 if LOG_BOOTLOADER_LEVEL_ERROR
|
||||
default 2 if LOG_BOOTLOADER_LEVEL_WARN
|
||||
default 3 if LOG_BOOTLOADER_LEVEL_INFO
|
||||
default 4 if LOG_BOOTLOADER_LEVEL_DEBUG
|
||||
default 5 if LOG_BOOTLOADER_LEVEL_VERBOSE
|
||||
|
||||
endmenu
|
||||
|
||||
|
||||
|
||||
menu "Security features"
|
||||
|
||||
config SECURE_BOOT_ENABLED
|
||||
bool "Enable secure boot in bootloader (READ DOCS FIRST)"
|
||||
default N
|
||||
help
|
||||
Build a bootloader which enables secure boot on first boot.
|
||||
|
||||
Once enabled, secure boot will not boot a modified bootloader. The bootloader will only load a partition table or boot an app if the data has a verified digital signature. There are implications for reflashing updated apps once secure boot is enabled.
|
||||
|
||||
When enabling secure boot, JTAG and ROM BASIC Interpreter are permanently disabled by default.
|
||||
|
||||
Refer to http://esp-idf.readthedocs.io/en/latest/security/secure-boot.html before enabling.
|
||||
|
||||
choice SECURE_BOOTLOADER_MODE
|
||||
bool "Secure bootloader mode"
|
||||
depends on SECURE_BOOT_ENABLED
|
||||
default SECURE_BOOTLOADER_ONE_TIME_FLASH
|
||||
|
||||
config SECURE_BOOTLOADER_ONE_TIME_FLASH
|
||||
bool "One-time flash"
|
||||
help
|
||||
On first boot, the bootloader will generate a key which is not readable externally or by software. A digest is generated from the bootloader image itself. This digest will be verified on each subsequent boot.
|
||||
|
||||
Enabling this option means that the bootloader cannot be changed after the first time it is booted.
|
||||
|
||||
config SECURE_BOOTLOADER_REFLASHABLE
|
||||
bool "Reflashable"
|
||||
help
|
||||
Generate a reusable secure bootloader key, derived (via SHA-256) from the secure boot signing key.
|
||||
|
||||
This allows the secure bootloader to be re-flashed by anyone with access to the secure boot signing key.
|
||||
|
||||
This option is less secure than one-time flash, because a leak of the digest key from one device allows reflashing of any device that uses it.
|
||||
|
||||
endchoice
|
||||
|
||||
config SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
bool "Sign binaries during build"
|
||||
depends on SECURE_BOOT_ENABLED
|
||||
default y
|
||||
help
|
||||
Once secure boot is enabled, bootloader will only boot if partition table and app image are signed.
|
||||
|
||||
If enabled, these binary files are signed as part of the build process. The file named in "Secure boot private signing key" will be used to sign the image.
|
||||
|
||||
If disabled, unsigned app/partition data will be built. They must be signed manually using espsecure.py (for example, on a remote signing server.)
|
||||
|
||||
config SECURE_BOOT_SIGNING_KEY
|
||||
string "Secure boot private signing key"
|
||||
depends on SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
default secure_boot_signing_key.pem
|
||||
help
|
||||
Path to the key file used to sign partition tables and app images for secure boot. Once secure boot is enabled, bootloader will only boot if partition table and app image are signed.
|
||||
|
||||
Key file is an ECDSA private key (NIST256p curve) in PEM format.
|
||||
|
||||
Path is evaluated relative to the project directory.
|
||||
|
||||
You can generate a new signing key by running the following command:
|
||||
espsecure.py generate_signing_key secure_boot_signing_key.pem
|
||||
|
||||
See docs/security/secure-boot.rst for details.
|
||||
|
||||
config SECURE_BOOT_VERIFICATION_KEY
|
||||
string "Secure boot public signature verification key"
|
||||
depends on SECURE_BOOT_ENABLED && !SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
default signature_verification_key.bin
|
||||
help
|
||||
Path to a public key file used to verify signed images. This key is compiled into the bootloader,
|
||||
and may also be used to verify signatures on OTA images after download.
|
||||
|
||||
Key file is in raw binary format, and can be extracted from a
|
||||
PEM formatted private key using the espsecure.py
|
||||
extract_public_key command.
|
||||
|
||||
Refer to http://esp-idf.readthedocs.io/en/latest/security/secure-boot.html before enabling.
|
||||
|
||||
config SECURE_BOOT_INSECURE
|
||||
bool "Allow potentially insecure options"
|
||||
depends on SECURE_BOOT_ENABLED
|
||||
default N
|
||||
help
|
||||
You can disable some of the default protections offered by secure boot, in order to enable testing or a custom combination of security features.
|
||||
|
||||
Only enable these options if you are very sure.
|
||||
|
||||
Refer to http://esp-idf.readthedocs.io/en/latest/security/secure-boot.html before enabling.
|
||||
|
||||
config FLASH_ENCRYPTION_ENABLED
|
||||
bool "Enable flash encryption on boot (READ DOCS FIRST)"
|
||||
default N
|
||||
help
|
||||
If this option is set, flash contents will be encrypted by the bootloader on first boot.
|
||||
|
||||
Note: After first boot, the system will be permanently encrypted. Re-flashing an encrypted
|
||||
system is complicated and not always possible.
|
||||
|
||||
Read http://esp-idf.readthedocs.io/en/latest/security/flash-encryption.html before enabling.
|
||||
|
||||
config FLASH_ENCRYPTION_INSECURE
|
||||
bool "Allow potentially insecure options"
|
||||
depends on FLASH_ENCRYPTION_ENABLED
|
||||
default N
|
||||
help
|
||||
You can disable some of the default protections offered by flash encryption, in order to enable testing or a custom combination of security features.
|
||||
|
||||
Only enable these options if you are very sure.
|
||||
|
||||
Refer to docs/security/secure-boot.rst and docs/security/flash-encryption.rst for details.
|
||||
|
||||
menu "Potentially insecure options"
|
||||
visible if FLASH_ENCRYPTION_INSECURE || SECURE_BOOT_INSECURE
|
||||
|
||||
# NOTE: Options in this menu NEED to have SECURE_BOOT_INSECURE
|
||||
# and/or FLASH_ENCRYPTION_INSECURE in "depends on", as the menu
|
||||
# itself doesn't enable/disable its children (if it's not set,
|
||||
# it's possible for the insecure menu to be disabled but the insecure option
|
||||
# to remain on which is very bad.)
|
||||
|
||||
config SECURE_BOOT_ALLOW_ROM_BASIC
|
||||
bool "Leave ROM BASIC Interpreter available on reset"
|
||||
depends on SECURE_BOOT_INSECURE
|
||||
default N
|
||||
help
|
||||
If not set (default), bootloader permanently disables ROM BASIC (on UART console) as a fallback if the bootloader image becomes invalid. This happens on first boot.
|
||||
|
||||
Only set this option in testing environments.
|
||||
|
||||
config SECURE_BOOT_ALLOW_JTAG
|
||||
bool "Allow JTAG Debugging"
|
||||
depends on SECURE_BOOT_INSECURE || FLASH_ENCRYPTION_INSECURE
|
||||
default N
|
||||
help
|
||||
If not set (default), the bootloader will permanently disable JTAG (across entire chip) on first boot when either secure boot or flash encryption is enabled.
|
||||
|
||||
Setting this option leaves JTAG on for debugging, which negates all protections of flash encryption and some of the protections of secure boot.
|
||||
|
||||
Only set this option in testing environments.
|
||||
|
||||
|
||||
config FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_ENCRYPT
|
||||
bool "Leave UART bootloader encryption enabled"
|
||||
depends on FLASH_ENCRYPTION_INSECURE
|
||||
default N
|
||||
help
|
||||
If not set (default), the bootloader will permanently disable UART bootloader encryption access on first boot. If set, the UART bootloader will still be able to access hardware encryption.
|
||||
|
||||
It is recommended to only set this option in testing environments.
|
||||
|
||||
config FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_DECRYPT
|
||||
bool "Leave UART bootloader decryption enabled"
|
||||
depends on FLASH_ENCRYPTION_INSECURE
|
||||
default N
|
||||
help
|
||||
If not set (default), the bootloader will permanently disable UART bootloader decryption access on first boot. If set, the UART bootloader will still be able to access hardware decryption.
|
||||
|
||||
Only set this option in testing environments. Setting this option allows complete bypass of flash encryption.
|
||||
|
||||
config FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_CACHE
|
||||
bool "Leave UART bootloader flash cache enabled"
|
||||
depends on FLASH_ENCRYPTION_INSECURE
|
||||
default N
|
||||
help
|
||||
If not set (default), the bootloader will permanently disable UART bootloader flash cache access on first boot. If set, the UART bootloader will still be able to access the flash cache.
|
||||
|
||||
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
|
||||
|
||||
endmenu
|
||||
@@ -8,44 +8,113 @@
|
||||
# basically runs Make in the src/ directory but it needs to zero some variables
|
||||
# the ESP-IDF project.mk makefile exports first, to not let them interfere.
|
||||
#
|
||||
ifeq ("$(IS_BOOTLOADER_BUILD)","")
|
||||
ifndef IS_BOOTLOADER_BUILD
|
||||
|
||||
BOOTLOADER_COMPONENT_PATH := $(COMPONENT_PATH)
|
||||
BOOTLOADER_BUILD_DIR=$(BUILD_DIR_BASE)/bootloader
|
||||
BOOTLOADER_BUILD_DIR=$(abspath $(BUILD_DIR_BASE)/bootloader)
|
||||
BOOTLOADER_BIN=$(BOOTLOADER_BUILD_DIR)/bootloader.bin
|
||||
|
||||
# signing key path is resolved relative to the project directory
|
||||
SECURE_BOOT_SIGNING_KEY=$(abspath $(call dequote,$(CONFIG_SECURE_BOOT_SIGNING_KEY)))
|
||||
export SECURE_BOOT_SIGNING_KEY # used by bootloader_support component
|
||||
|
||||
# Has a matching value in bootloader_support esp_flash_partitions.h
|
||||
BOOTLOADER_OFFSET := 0x1000
|
||||
|
||||
# Custom recursive make for bootloader sub-project
|
||||
BOOTLOADER_MAKE=+$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \
|
||||
V=$(V) BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) TEST_COMPONENTS=
|
||||
|
||||
.PHONY: bootloader-clean bootloader-flash bootloader $(BOOTLOADER_BIN)
|
||||
|
||||
$(BOOTLOADER_BIN): $(COMPONENT_PATH)/src/sdkconfig
|
||||
$(Q) PROJECT_PATH= \
|
||||
BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \
|
||||
$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src MAKEFLAGS= V=$(V) TARGET_BIN_LAYOUT="$(BOOTLOADER_TARGET_BIN_LAYOUT)" $(BOOTLOADER_BIN)
|
||||
|
||||
bootloader-clean:
|
||||
$(Q) PROJECT_PATH= \
|
||||
BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \
|
||||
$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src app-clean MAKEFLAGS= V=$(V)
|
||||
$(BOOTLOADER_BIN): $(SDKCONFIG_MAKEFILE)
|
||||
$(BOOTLOADER_MAKE) $@
|
||||
|
||||
clean: bootloader-clean
|
||||
|
||||
ifndef CONFIG_SECURE_BOOT_ENABLED
|
||||
# If secure boot disabled, bootloader flashing is integrated
|
||||
# with 'make flash' and no warnings are printed.
|
||||
|
||||
bootloader: $(BOOTLOADER_BIN)
|
||||
@echo $(SEPARATOR)
|
||||
@echo "Bootloader built. Default flash command is:"
|
||||
@echo "$(ESPTOOLPY_WRITE_FLASH) 0x1000 $(BOOTLOADER_BIN)"
|
||||
@echo "$(ESPTOOLPY_WRITE_FLASH) $(BOOTLOADER_OFFSET) $^"
|
||||
|
||||
all_binaries: $(BOOTLOADER_BIN)
|
||||
ESPTOOL_ALL_FLASH_ARGS += $(BOOTLOADER_OFFSET) $(BOOTLOADER_BIN)
|
||||
|
||||
ESPTOOL_ALL_FLASH_ARGS += 0x1000 $(BOOTLOADER_BIN)
|
||||
bootloader-flash: $(BOOTLOADER_BIN) $(call prereq_if_explicit,erase_flash)
|
||||
$(ESPTOOLPY_WRITE_FLASH) 0x1000 $^
|
||||
|
||||
# synchronise the project level config to the component's
|
||||
# config
|
||||
$(COMPONENT_PATH)/src/sdkconfig: $(PROJECT_PATH)/sdkconfig
|
||||
$(Q) cp $< $@
|
||||
else ifdef CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH
|
||||
|
||||
# bootloader-flash calls flash in the bootloader dummy project
|
||||
bootloader-flash: $(BOOTLOADER_BIN)
|
||||
$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src flash MAKEFLAGS= V=$(V)
|
||||
# One time flashing requires user to run esptool.py command themselves,
|
||||
# and warning is printed about inability to reflash.
|
||||
#
|
||||
# The flashing command is deliberately printed without an auto-reset
|
||||
# step, so the device doesn't immediately reset to flash itself.
|
||||
|
||||
bootloader: $(BOOTLOADER_BIN)
|
||||
@echo $(SEPARATOR)
|
||||
@echo "Bootloader built. One-time flash command is:"
|
||||
@echo "$(subst hard_reset,no_reset,$(ESPTOOLPY_WRITE_FLASH)) $(BOOTLOADER_OFFSET) $(BOOTLOADER_BIN)"
|
||||
@echo $(SEPARATOR)
|
||||
@echo "* IMPORTANT: After first boot, BOOTLOADER CANNOT BE RE-FLASHED on same device"
|
||||
|
||||
else ifdef CONFIG_SECURE_BOOTLOADER_REFLASHABLE
|
||||
# Reflashable secure bootloader
|
||||
# generates a digest binary (bootloader + digest)
|
||||
|
||||
BOOTLOADER_DIGEST_BIN := $(BOOTLOADER_BUILD_DIR)/bootloader-reflash-digest.bin
|
||||
SECURE_BOOTLOADER_KEY := $(BOOTLOADER_BUILD_DIR)/secure-bootloader-key.bin
|
||||
|
||||
ifdef CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
$(SECURE_BOOTLOADER_KEY): $(SECURE_BOOT_SIGNING_KEY)
|
||||
$(ESPSECUREPY) digest_private_key -k $< $@
|
||||
else
|
||||
$(SECURE_BOOTLOADER_KEY):
|
||||
@echo "No pre-generated key for a reflashable secure bootloader is available, due to signing configuration."
|
||||
@echo "To generate one, you can use this command:"
|
||||
@echo "espsecure.py generate_flash_encryption_key $@"
|
||||
@echo "then re-run make."
|
||||
exit 1
|
||||
endif
|
||||
|
||||
bootloader: $(BOOTLOADER_DIGEST_BIN)
|
||||
@echo $(SEPARATOR)
|
||||
@echo "Bootloader built and secure digest generated. First time flash command is:"
|
||||
@echo "$(ESPEFUSEPY) burn_key secure_boot $(SECURE_BOOTLOADER_KEY)"
|
||||
@echo "$(ESPTOOLPY_WRITE_FLASH) $(BOOTLOADER_OFFSET) $(BOOTLOADER_BIN)"
|
||||
@echo $(SEPARATOR)
|
||||
@echo "To reflash the bootloader after initial flash:"
|
||||
@echo "$(ESPTOOLPY_WRITE_FLASH) 0x0 $(BOOTLOADER_DIGEST_BIN)"
|
||||
@echo $(SEPARATOR)
|
||||
@echo "* After first boot, only re-flashes of this kind (with same key) will be accepted."
|
||||
@echo "* Not recommended to re-use the same secure boot keyfile on multiple production devices."
|
||||
|
||||
$(BOOTLOADER_DIGEST_BIN): $(BOOTLOADER_BIN) $(SECURE_BOOTLOADER_KEY)
|
||||
@echo "DIGEST $(notdir $@)"
|
||||
$(Q) $(ESPSECUREPY) digest_secure_bootloader -k $(SECURE_BOOTLOADER_KEY) -o $@ $<
|
||||
|
||||
else
|
||||
CFLAGS += -D BOOTLOADER_BUILD=1 -I $(IDF_PATH)/components/esp32/include
|
||||
bootloader:
|
||||
@echo "Invalid bootloader target: bad sdkconfig?"
|
||||
@exit 1
|
||||
endif
|
||||
|
||||
ifndef CONFIG_SECURE_BOOT_ENABLED
|
||||
# don't build bootloader by default is secure boot is enabled
|
||||
all_binaries: $(BOOTLOADER_BIN)
|
||||
endif
|
||||
|
||||
bootloader-clean:
|
||||
$(BOOTLOADER_MAKE) app-clean
|
||||
rm -f $(SECURE_BOOTLOADER_KEY) $(BOOTLOADER_DIGEST_BIN)
|
||||
|
||||
$(BOOTLOADER_BUILD_DIR):
|
||||
mkdir -p $@
|
||||
|
||||
else
|
||||
CFLAGS += -D BOOTLOADER_BUILD=1 -I $(IDF_PATH)/components/esp32/include
|
||||
|
||||
endif
|
||||
|
||||
@@ -4,14 +4,18 @@
|
||||
#
|
||||
|
||||
PROJECT_NAME := bootloader
|
||||
COMPONENTS := esptool_py bootloader log
|
||||
|
||||
#We cannot include the esp32 component directly but we need its includes.
|
||||
#This is fixed by adding CFLAGS from Makefile.projbuild
|
||||
COMPONENTS := esptool_py bootloader bootloader_support log spi_flash micro-ecc
|
||||
|
||||
# The bootloader pseudo-component is also included in this build, for its Kconfig.projbuild to be included.
|
||||
#
|
||||
# IS_BOOTLOADER_BUILD tells the component Makefile.projbuild to be a no-op
|
||||
IS_BOOTLOADER_BUILD := 1
|
||||
export IS_BOOTLOADER_BUILD
|
||||
|
||||
#We cannot include the esp32 component directly but we need its includes.
|
||||
#This is fixed by adding CFLAGS from Makefile.projbuild
|
||||
# include the top-level "project" include directory, for sdkconfig.h
|
||||
CFLAGS += -I$(BUILD_DIR_BASE)/../include
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
|
||||
4
components/bootloader/src/main/Makefile.projbuild
Normal file
4
components/bootloader/src/main/Makefile.projbuild
Normal file
@@ -0,0 +1,4 @@
|
||||
# Submodules normally added in component.mk, but fully qualified
|
||||
# paths can be added at this level (we need binary librtc to be
|
||||
# available to link bootloader).
|
||||
COMPONENT_SUBMODULES += $(IDF_PATH)/components/esp32/lib
|
||||
@@ -20,12 +20,10 @@
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#define BOOT_VERSION "V0.1"
|
||||
|
||||
#include "esp_flash_data_types.h"
|
||||
|
||||
#define SPI_SEC_SIZE 0x1000
|
||||
#define MEM_CACHE(offset) (uint8_t *)(0x3f400000 + (offset))
|
||||
#define CACHE_READ_32(offset) ((uint32_t *)(0x3f400000 + (offset)))
|
||||
#define PARTITION_ADD 0x4000
|
||||
#define PARTITION_MAGIC 0x50AA
|
||||
#define IROM_LOW 0x400D0000
|
||||
#define IROM_HIGH 0x40400000
|
||||
#define DROM_LOW 0x3F400000
|
||||
@@ -35,105 +33,18 @@ extern "C"
|
||||
#define RTC_DATA_LOW 0x50000000
|
||||
#define RTC_DATA_HIGH 0x50002000
|
||||
|
||||
/*spi mode,saved in third byte in flash */
|
||||
enum {
|
||||
SPI_MODE_QIO,
|
||||
SPI_MODE_QOUT,
|
||||
SPI_MODE_DIO,
|
||||
SPI_MODE_DOUT,
|
||||
SPI_MODE_FAST_READ,
|
||||
SPI_MODE_SLOW_READ
|
||||
};
|
||||
/* spi speed*/
|
||||
enum {
|
||||
SPI_SPEED_40M,
|
||||
SPI_SPEED_26M,
|
||||
SPI_SPEED_20M,
|
||||
SPI_SPEED_80M = 0xF
|
||||
};
|
||||
/*suppport flash size in esp32 */
|
||||
enum {
|
||||
SPI_SIZE_1MB = 0,
|
||||
SPI_SIZE_2MB,
|
||||
SPI_SIZE_4MB,
|
||||
SPI_SIZE_8MB,
|
||||
SPI_SIZE_16MB,
|
||||
SPI_SIZE_MAX
|
||||
};
|
||||
|
||||
|
||||
struct flash_hdr {
|
||||
char magic;
|
||||
char blocks;
|
||||
char spi_mode; /* flag of flash read mode in unpackage and usage in future */
|
||||
char spi_speed: 4; /* low bit */
|
||||
char spi_size: 4;
|
||||
unsigned int entry_addr;
|
||||
uint8_t encrypt_flag; /* encrypt flag */
|
||||
uint8_t secury_boot_flag; /* secury boot flag */
|
||||
char extra_header[14]; /* ESP32 additional header, unused by second bootloader */
|
||||
};
|
||||
|
||||
/* each header of flash bin block */
|
||||
struct block_hdr {
|
||||
unsigned int load_addr;
|
||||
unsigned int data_len;
|
||||
};
|
||||
|
||||
/* OTA selection structure (two copies in the OTA data partition.)
|
||||
|
||||
Size of 32 bytes is friendly to flash encryption */
|
||||
typedef struct {
|
||||
uint32_t ota_seq;
|
||||
uint8_t seq_label[24];
|
||||
uint32_t crc; /* CRC32 of ota_seq field only */
|
||||
} ota_select;
|
||||
|
||||
typedef struct {
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
} partition_pos_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t magic;
|
||||
uint8_t type; /* partition Type */
|
||||
uint8_t subtype; /* part_subtype */
|
||||
partition_pos_t pos;
|
||||
uint8_t label[16]; /* label for the partition */
|
||||
uint8_t reserved[4]; /* reserved */
|
||||
} partition_info_t;
|
||||
|
||||
#define PART_TYPE_APP 0x00
|
||||
#define PART_SUBTYPE_FACTORY 0x00
|
||||
#define PART_SUBTYPE_OTA_FLAG 0x10
|
||||
#define PART_SUBTYPE_OTA_MASK 0x0f
|
||||
#define PART_SUBTYPE_TEST 0x20
|
||||
|
||||
#define PART_TYPE_DATA 0x01
|
||||
#define PART_SUBTYPE_DATA_OTA 0x00
|
||||
#define PART_SUBTYPE_DATA_RF 0x01
|
||||
#define PART_SUBTYPE_DATA_WIFI 0x02
|
||||
|
||||
#define PART_TYPE_END 0xff
|
||||
#define PART_SUBTYPE_END 0xff
|
||||
|
||||
#define SPI_ERROR_LOG "spi flash error"
|
||||
|
||||
typedef struct {
|
||||
partition_pos_t ota_info;
|
||||
partition_pos_t factory;
|
||||
partition_pos_t test;
|
||||
partition_pos_t ota[16];
|
||||
esp_partition_pos_t ota_info;
|
||||
esp_partition_pos_t factory;
|
||||
esp_partition_pos_t test;
|
||||
esp_partition_pos_t ota[16];
|
||||
uint32_t app_count;
|
||||
uint32_t selected_subtype;
|
||||
} bootloader_state_t;
|
||||
|
||||
void boot_cache_redirect( uint32_t pos, size_t size );
|
||||
uint32_t get_bin_len(uint32_t pos);
|
||||
|
||||
bool flash_encrypt(bootloader_state_t *bs);
|
||||
bool secure_boot(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// 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
|
||||
@@ -23,6 +23,9 @@
|
||||
#include "rom/spi_flash.h"
|
||||
#include "rom/crc.h"
|
||||
#include "rom/rtc.h"
|
||||
#include "rom/uart.h"
|
||||
#include "rom/gpio.h"
|
||||
#include "rom/secure_boot.h"
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/cpu.h"
|
||||
@@ -31,10 +34,18 @@
|
||||
#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 "sdkconfig.h"
|
||||
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_random.h"
|
||||
#include "bootloader_config.h"
|
||||
#include "rtc.h"
|
||||
|
||||
extern int _bss_start;
|
||||
extern int _bss_end;
|
||||
@@ -49,16 +60,17 @@ flash cache is down and the app CPU is in reset. We do have a stack, so we can d
|
||||
extern void Cache_Flush(int);
|
||||
|
||||
void bootloader_main();
|
||||
void unpack_load_app(const partition_pos_t *app_node);
|
||||
void print_flash_info(struct flash_hdr* pfhdr);
|
||||
void IRAM_ATTR set_cache_and_start_app(uint32_t drom_addr,
|
||||
static void unpack_load_app(const esp_partition_pos_t *app_node);
|
||||
void print_flash_info(const esp_image_header_t* pfhdr);
|
||||
static void set_cache_and_start_app(uint32_t drom_addr,
|
||||
uint32_t drom_load_addr,
|
||||
uint32_t drom_size,
|
||||
uint32_t irom_addr,
|
||||
uint32_t irom_load_addr,
|
||||
uint32_t irom_size,
|
||||
uint32_t entry_addr);
|
||||
|
||||
static void update_flash_config(const esp_image_header_t* pfhdr);
|
||||
static void uart_console_configure(void);
|
||||
|
||||
void IRAM_ATTR call_start_cpu0()
|
||||
{
|
||||
@@ -93,53 +105,6 @@ void IRAM_ATTR call_start_cpu0()
|
||||
bootloader_main();
|
||||
}
|
||||
|
||||
/**
|
||||
* @function : get_bin_len
|
||||
* @description: get bin's length
|
||||
*
|
||||
* @inputs: pos bin locate address in flash
|
||||
* @return: uint32 length of bin,if bin MAGIC error return 0
|
||||
*/
|
||||
|
||||
uint32_t get_bin_len(uint32_t pos)
|
||||
{
|
||||
uint32_t len = 8 + 16;
|
||||
uint8_t i;
|
||||
ESP_LOGD(TAG, "pos %d %x",pos,*(uint8_t *)pos);
|
||||
if(0xE9 != *(uint8_t *)pos) {
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < *(uint8_t *)(pos + 1); i++) {
|
||||
len += *(uint32_t *)(pos + len + 4) + 8;
|
||||
}
|
||||
if (len % 16 != 0) {
|
||||
len = (len / 16 + 1) * 16;
|
||||
} else {
|
||||
len += 16;
|
||||
}
|
||||
ESP_LOGD(TAG, "bin length = %d", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @function : boot_cache_redirect
|
||||
* @description: Configure several pages in flash map so that `size` bytes
|
||||
* starting at `pos` are mapped to 0x3f400000.
|
||||
* This sets up mapping only for PRO CPU.
|
||||
*
|
||||
* @inputs: pos address in flash
|
||||
* size size of the area to map, in bytes
|
||||
*/
|
||||
void boot_cache_redirect( uint32_t pos, size_t size )
|
||||
{
|
||||
uint32_t pos_aligned = pos & 0xffff0000;
|
||||
uint32_t count = (size + 0xffff) / 0x10000;
|
||||
Cache_Read_Disable( 0 );
|
||||
Cache_Flush( 0 );
|
||||
ESP_LOGD(TAG, "mmu set paddr=%08x count=%d", pos_aligned, count );
|
||||
cache_flash_mmu_set( 0, 0, 0x3f400000, pos_aligned, 64, count );
|
||||
Cache_Read_Enable( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @function : load_partition_table
|
||||
@@ -147,95 +112,115 @@ void boot_cache_redirect( uint32_t pos, size_t size )
|
||||
* OTA info sector, factory app sector, and test app sector.
|
||||
*
|
||||
* @inputs: bs bootloader state structure used to save the data
|
||||
* addr address of partition table in flash
|
||||
* @return: return true, if the partition table is loaded (and MD5 checksum is valid)
|
||||
*
|
||||
*/
|
||||
bool load_partition_table(bootloader_state_t* bs, uint32_t addr)
|
||||
bool load_partition_table(bootloader_state_t* bs)
|
||||
{
|
||||
partition_info_t partition;
|
||||
uint32_t end = addr + 0x1000;
|
||||
int index = 0;
|
||||
const esp_partition_info_t *partitions;
|
||||
const int ESP_PARTITION_TABLE_DATA_LEN = 0xC00; /* length of actual data (signature is appended to this) */
|
||||
char *partition_usage;
|
||||
esp_err_t err;
|
||||
int num_partitions;
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
if(esp_secure_boot_enabled()) {
|
||||
ESP_LOGI(TAG, "Verifying partition table signature...");
|
||||
err = esp_secure_boot_verify_signature(ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_DATA_LEN);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to verify partition table signature.");
|
||||
return false;
|
||||
}
|
||||
ESP_LOGD(TAG, "Partition table signature verified");
|
||||
}
|
||||
#endif
|
||||
|
||||
partitions = bootloader_mmap(ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_DATA_LEN);
|
||||
if (!partitions) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_DATA_LEN);
|
||||
return false;
|
||||
}
|
||||
ESP_LOGD(TAG, "mapped partition table 0x%x at 0x%x", ESP_PARTITION_TABLE_ADDR, (intptr_t)partitions);
|
||||
|
||||
err = esp_partition_table_basic_verify(partitions, true, &num_partitions);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to verify partition table");
|
||||
return false;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Partition Table:");
|
||||
ESP_LOGI(TAG, "## Label Usage Type ST Offset Length");
|
||||
|
||||
while (addr < end) {
|
||||
ESP_LOGD(TAG, "load partition table entry from %x(%08x)", addr, MEM_CACHE(addr));
|
||||
memcpy(&partition, MEM_CACHE(addr), sizeof(partition));
|
||||
ESP_LOGD(TAG, "type=%x subtype=%x", partition.type, partition.subtype);
|
||||
for(int i = 0; i < num_partitions; i++) {
|
||||
const esp_partition_info_t *partition = &partitions[i];
|
||||
ESP_LOGD(TAG, "load partition table entry 0x%x", (intptr_t)partition);
|
||||
ESP_LOGD(TAG, "type=%x subtype=%x", partition->type, partition->subtype);
|
||||
partition_usage = "unknown";
|
||||
|
||||
if (partition.magic == PARTITION_MAGIC) { /* valid partition definition */
|
||||
switch(partition.type) {
|
||||
case PART_TYPE_APP: /* app partition */
|
||||
switch(partition.subtype) {
|
||||
case PART_SUBTYPE_FACTORY: /* factory binary */
|
||||
bs->factory = partition.pos;
|
||||
partition_usage = "factory app";
|
||||
break;
|
||||
case PART_SUBTYPE_TEST: /* test binary */
|
||||
bs->test = partition.pos;
|
||||
partition_usage = "test app";
|
||||
break;
|
||||
default:
|
||||
/* OTA binary */
|
||||
if ((partition.subtype & ~PART_SUBTYPE_OTA_MASK) == PART_SUBTYPE_OTA_FLAG) {
|
||||
bs->ota[partition.subtype & PART_SUBTYPE_OTA_MASK] = partition.pos;
|
||||
++bs->app_count;
|
||||
partition_usage = "OTA app";
|
||||
}
|
||||
else {
|
||||
partition_usage = "Unknown app";
|
||||
}
|
||||
break;
|
||||
/* valid partition table */
|
||||
switch(partition->type) {
|
||||
case PART_TYPE_APP: /* app partition */
|
||||
switch(partition->subtype) {
|
||||
case PART_SUBTYPE_FACTORY: /* factory binary */
|
||||
bs->factory = partition->pos;
|
||||
partition_usage = "factory app";
|
||||
break;
|
||||
case PART_SUBTYPE_TEST: /* test binary */
|
||||
bs->test = partition->pos;
|
||||
partition_usage = "test app";
|
||||
break;
|
||||
default:
|
||||
/* OTA binary */
|
||||
if ((partition->subtype & ~PART_SUBTYPE_OTA_MASK) == PART_SUBTYPE_OTA_FLAG) {
|
||||
bs->ota[partition->subtype & PART_SUBTYPE_OTA_MASK] = partition->pos;
|
||||
++bs->app_count;
|
||||
partition_usage = "OTA app";
|
||||
}
|
||||
break; /* PART_TYPE_APP */
|
||||
case PART_TYPE_DATA: /* data partition */
|
||||
switch(partition.subtype) {
|
||||
case PART_SUBTYPE_DATA_OTA: /* ota data */
|
||||
bs->ota_info = partition.pos;
|
||||
partition_usage = "OTA data";
|
||||
break;
|
||||
case PART_SUBTYPE_DATA_RF:
|
||||
partition_usage = "RF data";
|
||||
break;
|
||||
case PART_SUBTYPE_DATA_WIFI:
|
||||
partition_usage = "WiFi data";
|
||||
break;
|
||||
default:
|
||||
partition_usage = "Unknown data";
|
||||
break;
|
||||
else {
|
||||
partition_usage = "Unknown app";
|
||||
}
|
||||
break; /* PARTITION_USAGE_DATA */
|
||||
default: /* other partition type */
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* invalid partition magic number */
|
||||
else {
|
||||
break; /* todo: validate md5 */
|
||||
break; /* PART_TYPE_APP */
|
||||
case PART_TYPE_DATA: /* data partition */
|
||||
switch(partition->subtype) {
|
||||
case PART_SUBTYPE_DATA_OTA: /* ota data */
|
||||
bs->ota_info = partition->pos;
|
||||
partition_usage = "OTA data";
|
||||
break;
|
||||
case PART_SUBTYPE_DATA_RF:
|
||||
partition_usage = "RF data";
|
||||
break;
|
||||
case PART_SUBTYPE_DATA_WIFI:
|
||||
partition_usage = "WiFi data";
|
||||
break;
|
||||
default:
|
||||
partition_usage = "Unknown data";
|
||||
break;
|
||||
}
|
||||
break; /* PARTITION_USAGE_DATA */
|
||||
default: /* other partition type */
|
||||
break;
|
||||
}
|
||||
|
||||
/* print partition type info */
|
||||
ESP_LOGI(TAG, "%2d %-16s %-16s %02x %02x %08x %08x", index, partition.label, partition_usage,
|
||||
partition.type, partition.subtype,
|
||||
partition.pos.offset, partition.pos.size);
|
||||
index++;
|
||||
addr += sizeof(partition);
|
||||
ESP_LOGI(TAG, "%2d %-16s %-16s %02x %02x %08x %08x", i, partition->label, partition_usage,
|
||||
partition->type, partition->subtype,
|
||||
partition->pos.offset, partition->pos.size);
|
||||
}
|
||||
|
||||
bootloader_munmap(partitions);
|
||||
|
||||
ESP_LOGI(TAG,"End of partition table");
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32_t ota_select_crc(const ota_select *s)
|
||||
static uint32_t ota_select_crc(const esp_ota_select_entry_t *s)
|
||||
{
|
||||
return crc32_le(UINT32_MAX, (uint8_t*)&s->ota_seq, 4);
|
||||
}
|
||||
|
||||
static bool ota_select_valid(const ota_select *s)
|
||||
static bool ota_select_valid(const esp_ota_select_entry_t *s)
|
||||
{
|
||||
return s->ota_seq != UINT32_MAX && s->crc == ota_select_crc(s);
|
||||
}
|
||||
@@ -249,70 +234,104 @@ static bool ota_select_valid(const ota_select *s)
|
||||
|
||||
void bootloader_main()
|
||||
{
|
||||
ESP_LOGI(TAG, "Espressif ESP32 2nd stage bootloader v. %s", BOOT_VERSION);
|
||||
/* Set CPU to 80MHz.
|
||||
Start by ensuring it is set to XTAL, as PLL must be off first
|
||||
(may still be on due to soft reset.)
|
||||
*/
|
||||
rtc_set_cpu_freq(CPU_XTAL);
|
||||
rtc_set_cpu_freq(CPU_80M);
|
||||
|
||||
struct flash_hdr fhdr;
|
||||
uart_console_configure();
|
||||
ESP_LOGI(TAG, "ESP-IDF %s 2nd stage bootloader", IDF_VER);
|
||||
#if defined(CONFIG_SECURE_BOOT_ENABLED) || defined(CONFIG_FLASH_ENCRYPTION_ENABLED)
|
||||
esp_err_t err;
|
||||
#endif
|
||||
esp_image_header_t fhdr;
|
||||
bootloader_state_t bs;
|
||||
SpiFlashOpResult spiRet1,spiRet2;
|
||||
ota_select sa,sb;
|
||||
SpiFlashOpResult spiRet1,spiRet2;
|
||||
esp_ota_select_entry_t sa,sb;
|
||||
const esp_ota_select_entry_t *ota_select_map;
|
||||
|
||||
memset(&bs, 0, sizeof(bs));
|
||||
|
||||
ESP_LOGI(TAG, "compile time " __TIME__ );
|
||||
/* close watch dog here */
|
||||
/* disable watch dog here */
|
||||
REG_CLR_BIT( RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN );
|
||||
REG_CLR_BIT( TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN );
|
||||
SPIUnlock();
|
||||
/*register first sector in drom0 page 0 */
|
||||
boot_cache_redirect( 0, 0x5000 );
|
||||
|
||||
memcpy((unsigned int *) &fhdr, MEM_CACHE(0x1000), sizeof(struct flash_hdr) );
|
||||
ESP_LOGI(TAG, "Enabling RNG early entropy source...");
|
||||
bootloader_random_enable();
|
||||
|
||||
if(esp_image_load_header(0x1000, true, &fhdr) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "failed to load bootloader header!");
|
||||
return;
|
||||
}
|
||||
|
||||
print_flash_info(&fhdr);
|
||||
|
||||
if (!load_partition_table(&bs, PARTITION_ADD)) {
|
||||
update_flash_config(&fhdr);
|
||||
|
||||
if (!load_partition_table(&bs)) {
|
||||
ESP_LOGE(TAG, "load partition table error!");
|
||||
return;
|
||||
}
|
||||
|
||||
partition_pos_t load_part_pos;
|
||||
esp_partition_pos_t load_part_pos;
|
||||
|
||||
if (bs.ota_info.offset != 0) { // check if partition table has OTA info partition
|
||||
//ESP_LOGE("OTA info sector handling is not implemented");
|
||||
boot_cache_redirect(bs.ota_info.offset, bs.ota_info.size );
|
||||
memcpy(&sa,MEM_CACHE(bs.ota_info.offset & 0x0000ffff),sizeof(sa));
|
||||
memcpy(&sb,MEM_CACHE((bs.ota_info.offset + 0x1000)&0x0000ffff) ,sizeof(sb));
|
||||
if (bs.ota_info.size < 2 * SPI_SEC_SIZE) {
|
||||
ESP_LOGE(TAG, "ERROR: ota_info partition size %d is too small (minimum %d bytes)", bs.ota_info.size, sizeof(esp_ota_select_entry_t));
|
||||
return;
|
||||
}
|
||||
ota_select_map = bootloader_mmap(bs.ota_info.offset, bs.ota_info.size);
|
||||
if (!ota_select_map) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", bs.ota_info.offset, bs.ota_info.size);
|
||||
return;
|
||||
}
|
||||
memcpy(&sa, ota_select_map, sizeof(esp_ota_select_entry_t));
|
||||
memcpy(&sb, (uint8_t *)ota_select_map + SPI_SEC_SIZE, sizeof(esp_ota_select_entry_t));
|
||||
bootloader_munmap(ota_select_map);
|
||||
if(sa.ota_seq == 0xFFFFFFFF && sb.ota_seq == 0xFFFFFFFF) {
|
||||
// init status flash
|
||||
load_part_pos = bs.ota[0];
|
||||
sa.ota_seq = 0x01;
|
||||
sa.crc = ota_select_crc(&sa);
|
||||
sb.ota_seq = 0x00;
|
||||
sb.crc = ota_select_crc(&sb);
|
||||
// init status flash
|
||||
if (bs.factory.offset != 0) { // if have factory bin,boot factory bin
|
||||
load_part_pos = bs.factory;
|
||||
} else {
|
||||
load_part_pos = bs.ota[0];
|
||||
sa.ota_seq = 0x01;
|
||||
sa.crc = ota_select_crc(&sa);
|
||||
sb.ota_seq = 0x00;
|
||||
sb.crc = ota_select_crc(&sb);
|
||||
|
||||
Cache_Read_Disable(0);
|
||||
spiRet1 = SPIEraseSector(bs.ota_info.offset/0x1000);
|
||||
spiRet2 = SPIEraseSector(bs.ota_info.offset/0x1000+1);
|
||||
if (spiRet1 != SPI_FLASH_RESULT_OK || spiRet2 != SPI_FLASH_RESULT_OK ) {
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return;
|
||||
}
|
||||
spiRet1 = SPIWrite(bs.ota_info.offset,(uint32_t *)&sa,sizeof(ota_select));
|
||||
spiRet2 = SPIWrite(bs.ota_info.offset + 0x1000,(uint32_t *)&sb,sizeof(ota_select));
|
||||
if (spiRet1 != SPI_FLASH_RESULT_OK || spiRet2 != SPI_FLASH_RESULT_OK ) {
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return;
|
||||
}
|
||||
Cache_Read_Enable(0);
|
||||
Cache_Read_Disable(0);
|
||||
spiRet1 = SPIEraseSector(bs.ota_info.offset/0x1000);
|
||||
spiRet2 = SPIEraseSector(bs.ota_info.offset/0x1000+1);
|
||||
if (spiRet1 != SPI_FLASH_RESULT_OK || spiRet2 != SPI_FLASH_RESULT_OK ) {
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return;
|
||||
}
|
||||
spiRet1 = SPIWrite(bs.ota_info.offset,(uint32_t *)&sa,sizeof(esp_ota_select_entry_t));
|
||||
spiRet2 = SPIWrite(bs.ota_info.offset + 0x1000,(uint32_t *)&sb,sizeof(esp_ota_select_entry_t));
|
||||
if (spiRet1 != SPI_FLASH_RESULT_OK || spiRet2 != SPI_FLASH_RESULT_OK ) {
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return;
|
||||
}
|
||||
Cache_Read_Enable(0);
|
||||
}
|
||||
//TODO:write data in ota info
|
||||
} else {
|
||||
if(ota_select_valid(&sa) && ota_select_valid(&sb)) {
|
||||
load_part_pos = bs.ota[(((sa.ota_seq > sb.ota_seq)?sa.ota_seq:sb.ota_seq) - 1)%bs.app_count];
|
||||
}else if(ota_select_valid(&sa)) {
|
||||
} else if(ota_select_valid(&sa)) {
|
||||
load_part_pos = bs.ota[(sa.ota_seq - 1) % bs.app_count];
|
||||
}else if(ota_select_valid(&sb)) {
|
||||
} else if(ota_select_valid(&sb)) {
|
||||
load_part_pos = bs.ota[(sb.ota_seq - 1) % bs.app_count];
|
||||
}else {
|
||||
ESP_LOGE(TAG, "ota data partition info error");
|
||||
} else if (bs.factory.offset != 0) {
|
||||
ESP_LOGE(TAG, "ota data partition invalid, falling back to factory");
|
||||
load_part_pos = bs.factory;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "ota data partition invalid and no factory, can't boot");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -325,36 +344,76 @@ void bootloader_main()
|
||||
return;
|
||||
}
|
||||
|
||||
#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();
|
||||
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...
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FLASH_ENCRYPTION_ENABLED
|
||||
/* encrypt flash */
|
||||
ESP_LOGI(TAG, "Checking flash encryption...");
|
||||
bool flash_encryption_enabled = esp_flash_encryption_enabled();
|
||||
err = esp_flash_encrypt_check_and_update();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Flash encryption check failed (%d).", err);
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
cache resets properly */
|
||||
ESP_LOGI(TAG, "Resetting with flash encryption enabled...");
|
||||
REG_WRITE(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_SW_SYS_RST);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "Disabling RNG early entropy source...");
|
||||
bootloader_random_disable();
|
||||
|
||||
// copy loaded segments to RAM, set up caches for mapped segments, and start application
|
||||
ESP_LOGI(TAG, "Loading app partition at offset %08x", load_part_pos);
|
||||
if(fhdr.secury_boot_flag == 0x01) {
|
||||
/* protect the 2nd_boot */
|
||||
if(false == secure_boot()){
|
||||
ESP_LOGE(TAG, "secure boot failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(fhdr.encrypt_flag == 0x01) {
|
||||
/* encrypt flash */
|
||||
if (false == flash_encrypt(&bs)) {
|
||||
ESP_LOGE(TAG, "flash encrypt failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// copy sections to RAM, set up caches, and start application
|
||||
unpack_load_app(&load_part_pos);
|
||||
}
|
||||
|
||||
|
||||
void unpack_load_app(const partition_pos_t* partition)
|
||||
static void unpack_load_app(const esp_partition_pos_t* partition)
|
||||
{
|
||||
boot_cache_redirect(partition->offset, partition->size);
|
||||
esp_err_t err;
|
||||
esp_image_header_t image_header;
|
||||
uint32_t image_length;
|
||||
|
||||
uint32_t pos = 0;
|
||||
struct flash_hdr image_header;
|
||||
memcpy(&image_header, MEM_CACHE(pos), sizeof(image_header));
|
||||
pos += sizeof(image_header);
|
||||
/* TODO: verify the app image as part of OTA boot decision, so can have fallbacks */
|
||||
err = esp_image_basic_verify(partition->offset, true, &image_length);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to verify app image @ 0x%x (%d)", partition->offset, err);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
if (esp_secure_boot_enabled()) {
|
||||
ESP_LOGI(TAG, "Verifying app signature @ 0x%x (length 0x%x)", partition->offset, image_length);
|
||||
err = esp_secure_boot_verify_signature(partition->offset, image_length);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "App image @ 0x%x failed signature verification (%d)", partition->offset, err);
|
||||
return;
|
||||
}
|
||||
ESP_LOGD(TAG, "App signature is valid");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (esp_image_load_header(partition->offset, true, &image_header) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to load app image header @ 0x%x", partition->offset);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t drom_addr = 0;
|
||||
uint32_t drom_load_addr = 0;
|
||||
@@ -363,24 +422,30 @@ void unpack_load_app(const partition_pos_t* partition)
|
||||
uint32_t irom_load_addr = 0;
|
||||
uint32_t irom_size = 0;
|
||||
|
||||
/* Reload the RTC memory sections whenever a non-deepsleep reset
|
||||
is occuring */
|
||||
/* Reload the RTC memory segments whenever a non-deepsleep reset
|
||||
is occurring */
|
||||
bool load_rtc_memory = rtc_get_reset_reason(0) != DEEPSLEEP_RESET;
|
||||
|
||||
ESP_LOGD(TAG, "bin_header: %u %u %u %u %08x", image_header.magic,
|
||||
image_header.blocks,
|
||||
image_header.segment_count,
|
||||
image_header.spi_mode,
|
||||
image_header.spi_size,
|
||||
(unsigned)image_header.entry_addr);
|
||||
|
||||
for (uint32_t section_index = 0;
|
||||
section_index < image_header.blocks;
|
||||
++section_index) {
|
||||
struct block_hdr section_header = {0};
|
||||
memcpy(§ion_header, MEM_CACHE(pos), sizeof(section_header));
|
||||
pos += sizeof(section_header);
|
||||
/* Important: From here on this function cannot access any global data (bss/data segments),
|
||||
as loading the app image may overwrite these.
|
||||
*/
|
||||
for (int segment = 0; segment < image_header.segment_count; segment++) {
|
||||
esp_image_segment_header_t segment_header;
|
||||
uint32_t data_offs;
|
||||
if(esp_image_load_segment_header(segment, partition->offset,
|
||||
&image_header, true,
|
||||
&segment_header, &data_offs) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "failed to load segment header #%d", segment);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t address = section_header.load_addr;
|
||||
const uint32_t address = segment_header.load_addr;
|
||||
bool load = true;
|
||||
bool map = false;
|
||||
if (address == 0x00000000) { // padding, ignore block
|
||||
@@ -392,47 +457,75 @@ void unpack_load_app(const partition_pos_t* partition)
|
||||
}
|
||||
|
||||
if (address >= DROM_LOW && address < DROM_HIGH) {
|
||||
ESP_LOGD(TAG, "found drom section, map from %08x to %08x", pos,
|
||||
section_header.load_addr);
|
||||
drom_addr = partition->offset + pos - sizeof(section_header);
|
||||
drom_load_addr = section_header.load_addr;
|
||||
drom_size = section_header.data_len + sizeof(section_header);
|
||||
ESP_LOGD(TAG, "found drom segment, map from %08x to %08x", data_offs,
|
||||
segment_header.load_addr);
|
||||
drom_addr = data_offs;
|
||||
drom_load_addr = segment_header.load_addr;
|
||||
drom_size = segment_header.data_len + sizeof(segment_header);
|
||||
load = false;
|
||||
map = true;
|
||||
}
|
||||
|
||||
if (address >= IROM_LOW && address < IROM_HIGH) {
|
||||
ESP_LOGD(TAG, "found irom section, map from %08x to %08x", pos,
|
||||
section_header.load_addr);
|
||||
irom_addr = partition->offset + pos - sizeof(section_header);
|
||||
irom_load_addr = section_header.load_addr;
|
||||
irom_size = section_header.data_len + sizeof(section_header);
|
||||
ESP_LOGD(TAG, "found irom segment, map from %08x to %08x", data_offs,
|
||||
segment_header.load_addr);
|
||||
irom_addr = data_offs;
|
||||
irom_load_addr = segment_header.load_addr;
|
||||
irom_size = segment_header.data_len + sizeof(segment_header);
|
||||
load = false;
|
||||
map = true;
|
||||
}
|
||||
|
||||
if(!load_rtc_memory && address >= RTC_IRAM_LOW && address < RTC_IRAM_HIGH) {
|
||||
ESP_LOGD(TAG, "Skipping RTC code section at %08x\n", pos);
|
||||
load = false;
|
||||
}
|
||||
|
||||
if(!load_rtc_memory && address >= RTC_DATA_LOW && address < RTC_DATA_HIGH) {
|
||||
ESP_LOGD(TAG, "Skipping RTC data section at %08x\n", pos);
|
||||
load = false;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "section %d: paddr=0x%08x vaddr=0x%08x size=0x%05x (%6d) %s", section_index, pos,
|
||||
section_header.load_addr, section_header.data_len, section_header.data_len, (load)?"load":(map)?"map":"");
|
||||
|
||||
if (!load) {
|
||||
pos += section_header.data_len;
|
||||
continue;
|
||||
if (!load_rtc_memory && address >= RTC_IRAM_LOW && address < RTC_IRAM_HIGH) {
|
||||
ESP_LOGD(TAG, "Skipping RTC code segment at %08x\n", data_offs);
|
||||
load = false;
|
||||
}
|
||||
|
||||
memcpy((void*) section_header.load_addr, MEM_CACHE(pos), section_header.data_len);
|
||||
pos += section_header.data_len;
|
||||
if (!load_rtc_memory && address >= RTC_DATA_LOW && address < RTC_DATA_HIGH) {
|
||||
ESP_LOGD(TAG, "Skipping RTC data segment at %08x\n", data_offs);
|
||||
load = false;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "segment %d: paddr=0x%08x vaddr=0x%08x size=0x%05x (%6d) %s", segment, data_offs - sizeof(esp_image_segment_header_t),
|
||||
segment_header.load_addr, segment_header.data_len, segment_header.data_len, (load)?"load":(map)?"map":"");
|
||||
|
||||
if (load) {
|
||||
intptr_t sp, start_addr, end_addr;
|
||||
ESP_LOGV(TAG, "bootloader_mmap data_offs=%08x data_len=%08x", data_offs, segment_header.data_len);
|
||||
|
||||
start_addr = segment_header.load_addr;
|
||||
end_addr = start_addr + segment_header.data_len;
|
||||
|
||||
/* Before loading segment, check it doesn't clobber
|
||||
bootloader RAM... */
|
||||
|
||||
if (end_addr < 0x40000000) {
|
||||
sp = (intptr_t)get_sp();
|
||||
if (end_addr > sp) {
|
||||
ESP_LOGE(TAG, "Segment %d end address %08x overlaps bootloader stack %08x - can't load",
|
||||
segment, end_addr, sp);
|
||||
return;
|
||||
}
|
||||
if (end_addr > sp - 256) {
|
||||
/* We don't know for sure this is the stack high water mark, so warn if
|
||||
it seems like we may overflow.
|
||||
*/
|
||||
ESP_LOGW(TAG, "Segment %d end address %08x close to stack pointer %08x",
|
||||
segment, end_addr, sp);
|
||||
}
|
||||
}
|
||||
|
||||
const void *data = bootloader_mmap(data_offs, segment_header.data_len);
|
||||
if(!data) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%xc, 0x%x) failed",
|
||||
data_offs, segment_header.data_len);
|
||||
return;
|
||||
}
|
||||
memcpy((void *)segment_header.load_addr, data, segment_header.data_len);
|
||||
bootloader_munmap(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
set_cache_and_start_app(drom_addr,
|
||||
drom_load_addr,
|
||||
drom_size,
|
||||
@@ -442,7 +535,7 @@ void unpack_load_app(const partition_pos_t* partition)
|
||||
image_header.entry_addr);
|
||||
}
|
||||
|
||||
void IRAM_ATTR set_cache_and_start_app(
|
||||
static void set_cache_and_start_app(
|
||||
uint32_t drom_addr,
|
||||
uint32_t drom_load_addr,
|
||||
uint32_t drom_size,
|
||||
@@ -453,9 +546,7 @@ void IRAM_ATTR set_cache_and_start_app(
|
||||
{
|
||||
ESP_LOGD(TAG, "configure drom and irom and start");
|
||||
Cache_Read_Disable( 0 );
|
||||
Cache_Read_Disable( 1 );
|
||||
Cache_Flush( 0 );
|
||||
Cache_Flush( 1 );
|
||||
uint32_t drom_page_count = (drom_size + 64*1024 - 1) / (64*1024); // round up to 64k
|
||||
ESP_LOGV(TAG, "d mmu set paddr=%08x vaddr=%08x size=%d n=%d", drom_addr & 0xffff0000, drom_load_addr & 0xffff0000, drom_size, drom_page_count );
|
||||
int rc = cache_flash_mmu_set( 0, 0, drom_load_addr & 0xffff0000, drom_addr & 0xffff0000, 64, drom_page_count );
|
||||
@@ -471,7 +562,8 @@ void IRAM_ATTR set_cache_and_start_app(
|
||||
REG_CLR_BIT( DPORT_PRO_CACHE_CTRL1_REG, (DPORT_PRO_CACHE_MASK_IRAM0) | (DPORT_PRO_CACHE_MASK_IRAM1 & 0) | (DPORT_PRO_CACHE_MASK_IROM0 & 0) | DPORT_PRO_CACHE_MASK_DROM0 | DPORT_PRO_CACHE_MASK_DRAM1 );
|
||||
REG_CLR_BIT( DPORT_APP_CACHE_CTRL1_REG, (DPORT_APP_CACHE_MASK_IRAM0) | (DPORT_APP_CACHE_MASK_IRAM1 & 0) | (DPORT_APP_CACHE_MASK_IROM0 & 0) | DPORT_APP_CACHE_MASK_DROM0 | DPORT_APP_CACHE_MASK_DRAM1 );
|
||||
Cache_Read_Enable( 0 );
|
||||
Cache_Read_Enable( 1 );
|
||||
|
||||
// Application will need to do Cache_Flush(1) and Cache_Read_Enable(1)
|
||||
|
||||
ESP_LOGD(TAG, "start: 0x%08x", entry_addr);
|
||||
typedef void (*entry_t)(void);
|
||||
@@ -482,67 +574,84 @@ void IRAM_ATTR set_cache_and_start_app(
|
||||
(*entry)();
|
||||
}
|
||||
|
||||
static void update_flash_config(const esp_image_header_t* pfhdr)
|
||||
{
|
||||
uint32_t size;
|
||||
switch(pfhdr->spi_size) {
|
||||
case ESP_IMAGE_FLASH_SIZE_1MB:
|
||||
size = 1;
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_2MB:
|
||||
size = 2;
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_4MB:
|
||||
size = 4;
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_8MB:
|
||||
size = 8;
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_16MB:
|
||||
size = 16;
|
||||
break;
|
||||
default:
|
||||
size = 2;
|
||||
}
|
||||
Cache_Read_Disable( 0 );
|
||||
// Set flash chip size
|
||||
SPIParamCfg(g_rom_flashchip.deviceId, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
|
||||
// TODO: set mode
|
||||
// TODO: set frequency
|
||||
Cache_Flush(0);
|
||||
Cache_Read_Enable( 0 );
|
||||
}
|
||||
|
||||
void print_flash_info(struct flash_hdr* pfhdr)
|
||||
void print_flash_info(const esp_image_header_t* phdr)
|
||||
{
|
||||
#if (BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_NOTICE)
|
||||
|
||||
struct flash_hdr fhdr = *pfhdr;
|
||||
|
||||
ESP_LOGD(TAG, "magic %02x", fhdr.magic );
|
||||
ESP_LOGD(TAG, "blocks %02x", fhdr.blocks );
|
||||
ESP_LOGD(TAG, "spi_mode %02x", fhdr.spi_mode );
|
||||
ESP_LOGD(TAG, "spi_speed %02x", fhdr.spi_speed );
|
||||
ESP_LOGD(TAG, "spi_size %02x", fhdr.spi_size );
|
||||
ESP_LOGD(TAG, "magic %02x", phdr->magic );
|
||||
ESP_LOGD(TAG, "segments %02x", phdr->segment_count );
|
||||
ESP_LOGD(TAG, "spi_mode %02x", phdr->spi_mode );
|
||||
ESP_LOGD(TAG, "spi_speed %02x", phdr->spi_speed );
|
||||
ESP_LOGD(TAG, "spi_size %02x", phdr->spi_size );
|
||||
|
||||
const char* str;
|
||||
switch ( fhdr.spi_speed ) {
|
||||
case SPI_SPEED_40M:
|
||||
switch ( phdr->spi_speed ) {
|
||||
case ESP_IMAGE_SPI_SPEED_40M:
|
||||
str = "40MHz";
|
||||
break;
|
||||
|
||||
case SPI_SPEED_26M:
|
||||
case ESP_IMAGE_SPI_SPEED_26M:
|
||||
str = "26.7MHz";
|
||||
break;
|
||||
|
||||
case SPI_SPEED_20M:
|
||||
case ESP_IMAGE_SPI_SPEED_20M:
|
||||
str = "20MHz";
|
||||
break;
|
||||
|
||||
case SPI_SPEED_80M:
|
||||
case ESP_IMAGE_SPI_SPEED_80M:
|
||||
str = "80MHz";
|
||||
break;
|
||||
|
||||
default:
|
||||
str = "20MHz";
|
||||
break;
|
||||
}
|
||||
ESP_LOGI(TAG, "SPI Speed : %s", str );
|
||||
|
||||
|
||||
|
||||
switch ( fhdr.spi_mode ) {
|
||||
case SPI_MODE_QIO:
|
||||
switch ( phdr->spi_mode ) {
|
||||
case ESP_IMAGE_SPI_MODE_QIO:
|
||||
str = "QIO";
|
||||
break;
|
||||
|
||||
case SPI_MODE_QOUT:
|
||||
case ESP_IMAGE_SPI_MODE_QOUT:
|
||||
str = "QOUT";
|
||||
break;
|
||||
|
||||
case SPI_MODE_DIO:
|
||||
case ESP_IMAGE_SPI_MODE_DIO:
|
||||
str = "DIO";
|
||||
break;
|
||||
|
||||
case SPI_MODE_DOUT:
|
||||
case ESP_IMAGE_SPI_MODE_DOUT:
|
||||
str = "DOUT";
|
||||
break;
|
||||
|
||||
case SPI_MODE_FAST_READ:
|
||||
case ESP_IMAGE_SPI_MODE_FAST_READ:
|
||||
str = "FAST READ";
|
||||
break;
|
||||
|
||||
case SPI_MODE_SLOW_READ:
|
||||
case ESP_IMAGE_SPI_MODE_SLOW_READ:
|
||||
str = "SLOW READ";
|
||||
break;
|
||||
default:
|
||||
@@ -551,33 +660,81 @@ void print_flash_info(struct flash_hdr* pfhdr)
|
||||
}
|
||||
ESP_LOGI(TAG, "SPI Mode : %s", str );
|
||||
|
||||
|
||||
|
||||
switch ( fhdr.spi_size ) {
|
||||
case SPI_SIZE_1MB:
|
||||
switch ( phdr->spi_size ) {
|
||||
case ESP_IMAGE_FLASH_SIZE_1MB:
|
||||
str = "1MB";
|
||||
break;
|
||||
|
||||
case SPI_SIZE_2MB:
|
||||
case ESP_IMAGE_FLASH_SIZE_2MB:
|
||||
str = "2MB";
|
||||
break;
|
||||
|
||||
case SPI_SIZE_4MB:
|
||||
case ESP_IMAGE_FLASH_SIZE_4MB:
|
||||
str = "4MB";
|
||||
break;
|
||||
|
||||
case SPI_SIZE_8MB:
|
||||
case ESP_IMAGE_FLASH_SIZE_8MB:
|
||||
str = "8MB";
|
||||
break;
|
||||
|
||||
case SPI_SIZE_16MB:
|
||||
case ESP_IMAGE_FLASH_SIZE_16MB:
|
||||
str = "16MB";
|
||||
break;
|
||||
|
||||
default:
|
||||
str = "1MB";
|
||||
str = "2MB";
|
||||
break;
|
||||
}
|
||||
ESP_LOGI(TAG, "SPI Flash Size : %s", str );
|
||||
#endif
|
||||
}
|
||||
|
||||
static void uart_console_configure(void)
|
||||
{
|
||||
#if CONFIG_CONSOLE_UART_NONE
|
||||
ets_install_putc1(NULL);
|
||||
ets_install_putc2(NULL);
|
||||
#else // CONFIG_CONSOLE_UART_NONE
|
||||
const int uart_num = CONFIG_CONSOLE_UART_NUM;
|
||||
|
||||
uartAttach();
|
||||
ets_install_uart_printf();
|
||||
|
||||
// ROM bootloader may have put a lot of text into UART0 FIFO.
|
||||
// Wait for it to be printed.
|
||||
uart_tx_wait_idle(0);
|
||||
|
||||
#if CONFIG_CONSOLE_UART_CUSTOM
|
||||
// Some constants to make the following code less upper-case
|
||||
const int uart_tx_gpio = CONFIG_CONSOLE_UART_TX_GPIO;
|
||||
const int uart_rx_gpio = CONFIG_CONSOLE_UART_RX_GPIO;
|
||||
// Switch to the new UART (this just changes UART number used for
|
||||
// ets_printf in ROM code).
|
||||
uart_tx_switch(uart_num);
|
||||
// If console is attached to UART1 or if non-default pins are used,
|
||||
// need to reconfigure pins using GPIO matrix
|
||||
if (uart_num != 0 || uart_tx_gpio != 1 || uart_rx_gpio != 3) {
|
||||
// Change pin mode for GPIO1/3 from UART to GPIO
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_GPIO3);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_GPIO1);
|
||||
// Route GPIO signals to/from pins
|
||||
// (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 tx_idx = tx_idx_list[uart_num];
|
||||
const uint32_t rx_idx = rx_idx_list[uart_num];
|
||||
gpio_matrix_out(uart_tx_gpio, tx_idx, 0, 0);
|
||||
gpio_matrix_in(uart_rx_gpio, rx_idx, 0);
|
||||
}
|
||||
#endif // CONFIG_CONSOLE_UART_CUSTOM
|
||||
|
||||
// Set configured UART console baud rate
|
||||
const int uart_baud = CONFIG_CONSOLE_UART_BAUDRATE;
|
||||
uart_div_modify(uart_num, (APB_CLK_FREQ << 4) / uart_baud);
|
||||
|
||||
#endif // CONFIG_CONSOLE_UART_NONE
|
||||
}
|
||||
|
||||
/* empty rtc_printf implementation, to work with librtc
|
||||
linking. Can be removed once -lrtc is removed from bootloader's
|
||||
main component.mk.
|
||||
*/
|
||||
int rtc_printf(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,23 @@
|
||||
#
|
||||
# Main Makefile. This is basically the same as a component makefile.
|
||||
# Main bootloader Makefile.
|
||||
#
|
||||
# This Makefile should, at the very least, just include $(IDF_PATH)/make/component_common.mk. By default,
|
||||
# this will take the sources in the src/ directory, compile them and link them into
|
||||
# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
|
||||
# please read the esp-idf build system document if you need to do this.
|
||||
# This is basically the same as a component makefile, but in the case of the bootloader
|
||||
# we pull in bootloader-specific linker arguments.
|
||||
#
|
||||
|
||||
COMPONENT_ADD_LDFLAGS := -L $(abspath .) -lmain -T esp32.bootloader.ld -T $(IDF_PATH)/components/esp32/ld/esp32.rom.ld
|
||||
LINKER_SCRIPTS := \
|
||||
esp32.bootloader.ld \
|
||||
$(IDF_PATH)/components/esp32/ld/esp32.rom.ld \
|
||||
esp32.bootloader.rom.ld
|
||||
|
||||
include $(IDF_PATH)/make/component_common.mk
|
||||
COMPONENT_ADD_LDFLAGS := -L $(COMPONENT_PATH) -lmain $(addprefix -T ,$(LINKER_SCRIPTS))
|
||||
|
||||
COMPONENT_ADD_LINKER_DEPS := $(LINKER_SCRIPTS)
|
||||
|
||||
# following lines are a workaround to link librtc into the
|
||||
# bootloader, until clock setting code is in a source-based esp-idf
|
||||
# component. See also rtc_printf() in bootloader_start.c
|
||||
#
|
||||
# See also matching COMPONENT_SUBMODULES line in Makefile.projbuild
|
||||
COMPONENT_ADD_LDFLAGS += -L $(IDF_PATH)/components/esp32/lib/ -lrtc_clk -lrtc
|
||||
COMPONENT_EXTRA_INCLUDES += $(IDF_PATH)/components/esp32/
|
||||
|
||||
@@ -15,9 +15,9 @@ MEMORY
|
||||
of the various regions. The 'data access port' dram/drom regions map to the same iram/irom regions but
|
||||
are connected to the data port of the CPU and eg allow bytewise access. */
|
||||
dport0_seg (RW) : org = 0x3FF00000, len = 0x10 /* IO */
|
||||
iram_seg (RWX) : org = 0x40098000, len = 0x1000
|
||||
iram_seg (RWX) : org = 0x40080000, len = 0x400 /* 1k of IRAM used by bootloader functions which need to flush/enable APP CPU cache */
|
||||
iram_pool_1_seg (RWX) : org = 0x40078000, len = 0x8000 /* IRAM POOL1, used for APP CPU cache. We can abuse it in bootloader because APP CPU is still held in reset, until we enable APP CPU cache */
|
||||
dram_seg (RW) : org = 0x3FFC0000, len = 0x20000 /* Shared RAM, minus rom bss/data/stack.*/
|
||||
dram_seg (RW) : org = 0x3FFF0000, len = 0x10000 /* 64k at the end of DRAM, after ROM bootloader stack */
|
||||
}
|
||||
|
||||
/* Default entry point: */
|
||||
|
||||
1
components/bootloader/src/main/esp32.bootloader.rom.ld
Normal file
1
components/bootloader/src/main/esp32.bootloader.rom.ld
Normal file
@@ -0,0 +1 @@
|
||||
PROVIDE ( ets_update_cpu_frequency = 0x40008550 ); /* Updates g_ticks_per_us on the current CPU only; not on the other core */
|
||||
@@ -1,192 +0,0 @@
|
||||
// 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 <string.h>
|
||||
|
||||
#include "esp_types.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "rom/cache.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "rom/spi_flash.h"
|
||||
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "bootloader_config.h"
|
||||
|
||||
static const char* TAG = "flash_encrypt";
|
||||
|
||||
/**
|
||||
* @function : bitcount
|
||||
* @description: calculate bit 1 in flash_crypt_cnt
|
||||
* if it's even number, need encrypt flash data, and burn efuse
|
||||
*
|
||||
* @inputs: n flash_crypt_cnt
|
||||
* @return: number of 1 in flash_crypt_cnt
|
||||
*
|
||||
*/
|
||||
int bitcount(int n){
|
||||
int count = 0;
|
||||
while (n > 0) {
|
||||
count += n & 1;
|
||||
n >>= 1;
|
||||
}
|
||||
return count;
|
||||
|
||||
}
|
||||
/**
|
||||
* @function : flash_encrypt_write
|
||||
* @description: write encrypted data in flash
|
||||
*
|
||||
* @inputs: pos address in flash
|
||||
* len size of data need encrypt
|
||||
* @return: return true, if the write flash success
|
||||
*
|
||||
*/
|
||||
bool flash_encrypt_write(uint32_t pos, uint32_t len)
|
||||
{
|
||||
SpiFlashOpResult spiRet;
|
||||
uint32_t buf[1024];
|
||||
int i = 0;
|
||||
Cache_Read_Disable(0);
|
||||
for (i = 0;i<((len-1)/0x1000 + 1);i++) {
|
||||
spiRet = SPIRead(pos, buf, SPI_SEC_SIZE);
|
||||
if (spiRet != SPI_FLASH_RESULT_OK) {
|
||||
Cache_Read_Enable(0);
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return false;
|
||||
}
|
||||
spiRet = SPIEraseSector(pos/SPI_SEC_SIZE);
|
||||
if (spiRet != SPI_FLASH_RESULT_OK) {
|
||||
Cache_Read_Enable(0);
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return false;
|
||||
}
|
||||
spiRet = SPI_Encrypt_Write(pos, buf, SPI_SEC_SIZE);
|
||||
if (spiRet != SPI_FLASH_RESULT_OK) {
|
||||
Cache_Read_Enable(0);
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return false;
|
||||
}
|
||||
pos += SPI_SEC_SIZE;
|
||||
}
|
||||
Cache_Read_Enable(0);
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* @function : flash_encrypt
|
||||
* @description: encrypt 2nd boot ,partition table ,factory bin <20><>test bin (if use)<29><>ota bin
|
||||
* <20><>OTA info sector.
|
||||
*
|
||||
* @inputs: bs bootloader state structure used to save the data
|
||||
*
|
||||
* @return: return true, if the encrypt flash success
|
||||
*
|
||||
*/
|
||||
bool flash_encrypt(bootloader_state_t *bs)
|
||||
{
|
||||
uint32_t bin_len = 0;
|
||||
uint32_t flash_crypt_cnt = REG_GET_FIELD(EFUSE_BLK0_RDATA0_REG, EFUSE_FLASH_CRYPT_CNT);
|
||||
uint8_t count = bitcount(flash_crypt_cnt);
|
||||
int i = 0;
|
||||
ESP_LOGD(TAG, "flash encrypt cnt %x, bitcount %d", flash_crypt_cnt, count);
|
||||
|
||||
if ((count % 2) == 0) {
|
||||
boot_cache_redirect( 0, 64*1024);
|
||||
/* encrypt iv and abstruct */
|
||||
if (false == flash_encrypt_write(0, SPI_SEC_SIZE)) {
|
||||
ESP_LOGE(TAG, "encrypt iv and abstract error");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* encrypt write boot bin*/
|
||||
bin_len = get_bin_len((uint32_t)MEM_CACHE(0x1000));
|
||||
if(bin_len != 0) {
|
||||
if (false == flash_encrypt_write(0x1000, bin_len)) {
|
||||
ESP_LOGE(TAG, "encrypt 2nd boot error");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "2nd boot len error");
|
||||
return false;
|
||||
}
|
||||
/* encrypt partition table */
|
||||
if (false == flash_encrypt_write(PARTITION_ADD, SPI_SEC_SIZE)) {
|
||||
ESP_LOGE(TAG, "encrypt partition table error");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* encrypt write factory bin */
|
||||
if(bs->factory.offset != 0x00) {
|
||||
ESP_LOGD(TAG, "have factory bin");
|
||||
boot_cache_redirect(bs->factory.offset, bs->factory.size);
|
||||
bin_len = get_bin_len((uint32_t)MEM_CACHE(bs->factory.offset&0xffff));
|
||||
if(bin_len != 0) {
|
||||
if (false == flash_encrypt_write(bs->factory.offset, bin_len)) {
|
||||
ESP_LOGE(TAG, "encrypt factory bin error");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* encrypt write test bin */
|
||||
if(bs->test.offset != 0x00) {
|
||||
ESP_LOGD(TAG, "have test bin");
|
||||
boot_cache_redirect(bs->test.offset, bs->test.size);
|
||||
bin_len = get_bin_len((uint32_t)MEM_CACHE(bs->test.offset&0xffff));
|
||||
if(bin_len != 0) {
|
||||
if (false == flash_encrypt_write(bs->test.offset, bin_len)) {
|
||||
ESP_LOGE(TAG, "encrypt test bin error");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* encrypt write ota bin */
|
||||
for (i = 0;i<16;i++) {
|
||||
if(bs->ota[i].offset != 0x00) {
|
||||
ESP_LOGD(TAG, "have ota[%d] bin",i);
|
||||
boot_cache_redirect(bs->ota[i].offset, bs->ota[i].size);
|
||||
bin_len = get_bin_len((uint32_t)MEM_CACHE(bs->ota[i].offset&0xffff));
|
||||
if(bin_len != 0) {
|
||||
if (false == flash_encrypt_write(bs->ota[i].offset, bin_len)) {
|
||||
ESP_LOGE(TAG, "encrypt ota bin error");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* encrypt write ota info bin */
|
||||
if (false == flash_encrypt_write(bs->ota_info.offset, 2*SPI_SEC_SIZE)) {
|
||||
ESP_LOGE(TAG, "encrypt ota info error");
|
||||
return false;
|
||||
}
|
||||
REG_SET_FIELD(EFUSE_BLK0_WDATA0_REG, EFUSE_FLASH_CRYPT_CNT, 0x04);
|
||||
REG_WRITE(EFUSE_CONF_REG, 0x5A5A); /* efuse_pgm_op_ena, force no rd/wr disable */
|
||||
REG_WRITE(EFUSE_CMD_REG, 0x02); /* efuse_pgm_cmd */
|
||||
while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_pagm_cmd=0 */
|
||||
ESP_LOGW(TAG, "burn flash_crypt_cnt");
|
||||
REG_WRITE(EFUSE_CONF_REG, 0x5AA5); /* efuse_read_op_ena, release force */
|
||||
REG_WRITE(EFUSE_CMD_REG, 0x01); /* efuse_read_cmd */
|
||||
while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_read_cmd=0 */
|
||||
return true;
|
||||
} else {
|
||||
ESP_LOGI(TAG, "flash already encrypted.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
// 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 <string.h>
|
||||
|
||||
#include "esp_attr.h"
|
||||
#include "esp_types.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "rom/cache.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "rom/spi_flash.h"
|
||||
#include "rom/secure_boot.h"
|
||||
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "bootloader_config.h"
|
||||
|
||||
static const char* TAG = "secure_boot";
|
||||
|
||||
/**
|
||||
* @function : secure_boot_generate
|
||||
* @description: generate boot abstract & iv
|
||||
*
|
||||
* @inputs: bool
|
||||
*/
|
||||
bool secure_boot_generate(uint32_t bin_len){
|
||||
SpiFlashOpResult spiRet;
|
||||
uint16_t i;
|
||||
uint32_t buf[32];
|
||||
if (bin_len % 128 != 0) {
|
||||
bin_len = (bin_len / 128 + 1) * 128;
|
||||
}
|
||||
ets_secure_boot_start();
|
||||
ets_secure_boot_rd_iv(buf);
|
||||
ets_secure_boot_hash(NULL);
|
||||
Cache_Read_Disable(0);
|
||||
/* iv stored in sec 0 */
|
||||
spiRet = SPIEraseSector(0);
|
||||
if (spiRet != SPI_FLASH_RESULT_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return false;
|
||||
}
|
||||
/* write iv to flash, 0x0000, 128 bytes (1024 bits) */
|
||||
spiRet = SPIWrite(0, buf, 128);
|
||||
if (spiRet != SPI_FLASH_RESULT_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return false;
|
||||
}
|
||||
ESP_LOGD(TAG, "write iv to flash.");
|
||||
Cache_Read_Enable(0);
|
||||
/* read 4K code image from flash, for test */
|
||||
for (i = 0; i < bin_len; i+=128) {
|
||||
ets_secure_boot_hash((uint32_t *)(0x3f400000 + 0x1000 + i));
|
||||
}
|
||||
|
||||
ets_secure_boot_obtain();
|
||||
ets_secure_boot_rd_abstract(buf);
|
||||
ets_secure_boot_finish();
|
||||
Cache_Read_Disable(0);
|
||||
/* write abstract to flash, 0x0080, 64 bytes (512 bits) */
|
||||
spiRet = SPIWrite(0x80, buf, 64);
|
||||
if (spiRet != SPI_FLASH_RESULT_OK) {
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return false;
|
||||
}
|
||||
ESP_LOGD(TAG, "write abstract to flash.");
|
||||
Cache_Read_Enable(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @function : secure_boot
|
||||
* @description: protect boot code in flash
|
||||
*
|
||||
* @inputs: bool
|
||||
*/
|
||||
bool secure_boot(void){
|
||||
uint32_t bin_len = 0;
|
||||
if (REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_RD_ABS_DONE_0)
|
||||
{
|
||||
ESP_LOGD(TAG, "already secure boot !");
|
||||
return true;
|
||||
} else {
|
||||
boot_cache_redirect( 0, 64*1024);
|
||||
bin_len = get_bin_len((uint32_t)MEM_CACHE(0x1000));
|
||||
if (bin_len == 0) {
|
||||
ESP_LOGE(TAG, "boot len is error");
|
||||
return false;
|
||||
}
|
||||
if (false == secure_boot_generate(bin_len)){
|
||||
ESP_LOGE(TAG, "secure boot generate failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
REG_SET_BIT(EFUSE_BLK0_WDATA6_REG, EFUSE_RD_ABS_DONE_0);
|
||||
REG_WRITE(EFUSE_CONF_REG, 0x5A5A); /* efuse_pgm_op_ena, force no rd/wr disable */
|
||||
REG_WRITE(EFUSE_CMD_REG, 0x02); /* efuse_pgm_cmd */
|
||||
while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_pagm_cmd=0 */
|
||||
ESP_LOGW(TAG, "burn abstract_done_0");
|
||||
REG_WRITE(EFUSE_CONF_REG, 0x5AA5); /* efuse_read_op_ena, release force */
|
||||
REG_WRITE(EFUSE_CMD_REG, 0x01); /* efuse_read_cmd */
|
||||
while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_read_cmd=0 */
|
||||
ESP_LOGI(TAG, "read EFUSE_BLK0_RDATA6 %x", REG_READ(EFUSE_BLK0_RDATA6_REG));
|
||||
return true;
|
||||
|
||||
}
|
||||
7
components/bootloader_support/Makefile.projbuild
Normal file
7
components/bootloader_support/Makefile.projbuild
Normal file
@@ -0,0 +1,7 @@
|
||||
$(SECURE_BOOT_SIGNING_KEY):
|
||||
@echo "Need to generate secure boot signing key."
|
||||
@echo "One way is to run this command:"
|
||||
@echo "$(ESPSECUREPY) generate_signing_key $@"
|
||||
@echo "Keep key file safe after generating."
|
||||
@echo "(See secure boot documentation for risks & alternatives.)"
|
||||
@exit 1
|
||||
9
components/bootloader_support/README.rst
Normal file
9
components/bootloader_support/README.rst
Normal file
@@ -0,0 +1,9 @@
|
||||
Bootloader Support Component
|
||||
============================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
"Bootloader support" contains APIs which are used by the bootloader but are also needed for the main app.
|
||||
|
||||
Code in this component needs to be aware of being executed in a bootloader environment (no RTOS available, BOOTLOADER_BUILD macro set) or in an esp-idf app environment (RTOS running, need locking support.)
|
||||
45
components/bootloader_support/component.mk
Executable file
45
components/bootloader_support/component.mk
Executable file
@@ -0,0 +1,45 @@
|
||||
COMPONENT_ADD_INCLUDEDIRS := include
|
||||
COMPONENT_PRIV_INCLUDEDIRS := include_priv
|
||||
|
||||
ifdef IS_BOOTLOADER_BUILD
|
||||
# share "private" headers with the bootloader component
|
||||
# eventual goal: all functionality that needs this lives in bootloader_support
|
||||
COMPONENT_ADD_INCLUDEDIRS += include_priv
|
||||
endif
|
||||
|
||||
COMPONENT_SRCDIRS := src
|
||||
|
||||
#
|
||||
# Secure boot signing key support
|
||||
#
|
||||
ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
|
||||
# this path is created relative to the component build directory
|
||||
SECURE_BOOT_VERIFICATION_KEY := $(abspath signature_verification_key.bin)
|
||||
|
||||
ifdef CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
# verification key derived from signing key.
|
||||
$(SECURE_BOOT_VERIFICATION_KEY): $(SECURE_BOOT_SIGNING_KEY) $(SDKCONFIG_MAKEFILE)
|
||||
$(ESPSECUREPY) extract_public_key --keyfile $< $@
|
||||
else
|
||||
# find the configured public key file
|
||||
ORIG_SECURE_BOOT_VERIFICATION_KEY := $(call resolvepath,$(call dequote,$(CONFIG_SECURE_BOOT_VERIFICATION_KEY)),$(PROJECT_PATH))
|
||||
|
||||
$(ORIG_SECURE_BOOT_VERIFICATION_KEY):
|
||||
@echo "Secure boot verification public key '$@' missing."
|
||||
@echo "This can be extracted from the private signing key, see"
|
||||
@echo "docs/security/secure-boot.rst for details."
|
||||
exit 1
|
||||
|
||||
# copy it into the build dir, so the secure boot verification key has
|
||||
# a predictable file name
|
||||
$(SECURE_BOOT_VERIFICATION_KEY): $(ORIG_SECURE_BOOT_VERIFICATION_KEY) $(SDKCONFIG_MAKEFILE)
|
||||
$(summary) CP $< $@
|
||||
cp $< $@
|
||||
endif
|
||||
|
||||
COMPONENT_EXTRA_CLEAN += $(SECURE_BOOT_VERIFICATION_KEY)
|
||||
|
||||
COMPONENT_EMBED_FILES := $(SECURE_BOOT_VERIFICATION_KEY)
|
||||
|
||||
endif
|
||||
56
components/bootloader_support/include/esp_efuse.h
Normal file
56
components/bootloader_support/include/esp_efuse.h
Normal file
@@ -0,0 +1,56 @@
|
||||
// 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 _ESP_EFUSE_H
|
||||
#define _ESP_EFUSE_H
|
||||
|
||||
#include "soc/efuse_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* @brief Permanently update values written to the efuse write registers
|
||||
*
|
||||
* After updating EFUSE_BLKx_WDATAx_REG registers with new values to
|
||||
* write, call this function to permanently write them to efuse.
|
||||
*
|
||||
* @note Setting bits in efuse is permanent, they cannot be unset.
|
||||
*
|
||||
* @note Due to this restriction you don't need to copy values to
|
||||
* Efuse write registers from the matching read registers, bits which
|
||||
* are set in the read register but unset in the matching write
|
||||
* register will be unchanged when new values are burned.
|
||||
*
|
||||
* @note This function is not threadsafe, if calling code updates
|
||||
* efuse values from multiple tasks then this is caller's
|
||||
* responsibility to serialise.
|
||||
*
|
||||
* After burning new efuses, the read registers are updated to match
|
||||
* the new efuse values.
|
||||
*/
|
||||
void esp_efuse_burn_new_values(void);
|
||||
|
||||
/* @brief Reset efuse write registers
|
||||
*
|
||||
* Efuse write registers are written to zero, to negate
|
||||
* any changes that have been staged here.
|
||||
*/
|
||||
void esp_efuse_reset(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_EFUSE_H */
|
||||
|
||||
102
components/bootloader_support/include/esp_flash_encrypt.h
Normal file
102
components/bootloader_support/include/esp_flash_encrypt.h
Normal file
@@ -0,0 +1,102 @@
|
||||
// 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 __ESP32_FLASH_ENCRYPT_H
|
||||
#define __ESP32_FLASH_ENCRYPT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "esp_attr.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_spi_flash.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
|
||||
/**
|
||||
* @file esp_partition.h
|
||||
* @brief Support functions for flash encryption features
|
||||
*
|
||||
* Can be compiled as part of app or bootloader code.
|
||||
*/
|
||||
|
||||
/** @brief Is flash encryption currently enabled in hardware?
|
||||
*
|
||||
* Flash encryption is enabled if the FLASH_CRYPT_CNT efuse has an odd number of bits set.
|
||||
*
|
||||
* @return true if flash encryption is enabled.
|
||||
*/
|
||||
static inline IRAM_ATTR bool esp_flash_encryption_enabled(void) {
|
||||
uint32_t flash_crypt_cnt = REG_GET_FIELD(EFUSE_BLK0_RDATA0_REG, EFUSE_RD_FLASH_CRYPT_CNT);
|
||||
/* __builtin_parity is in flash, so we calculate parity inline */
|
||||
bool enabled = false;
|
||||
while(flash_crypt_cnt) {
|
||||
if (flash_crypt_cnt & 1) {
|
||||
enabled = !enabled;
|
||||
}
|
||||
flash_crypt_cnt >>= 1;
|
||||
}
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/* @brief Update on-device flash encryption
|
||||
*
|
||||
* Intended to be called as part of the bootloader process if flash
|
||||
* encryption is enabled in device menuconfig.
|
||||
*
|
||||
* If FLASH_CRYPT_CNT efuse parity is 1 (ie odd number of bits set),
|
||||
* then return ESP_OK immediately (indicating flash encryption is enabled
|
||||
* and functional).
|
||||
*
|
||||
* If FLASH_CRYPT_CNT efuse parity is 0 (ie even number of bits set),
|
||||
* assume the flash has just been written with plaintext that needs encrypting.
|
||||
*
|
||||
* The following regions of flash are encrypted in place:
|
||||
*
|
||||
* - The bootloader image, if a valid plaintext image is found.[*]
|
||||
* - The partition table, if a valid plaintext table is found.
|
||||
* - Any app partition that contains a valid plaintext app image.
|
||||
* - Any other partitions with the "encrypt" flag set. [**]
|
||||
*
|
||||
* After the re-encryption process completes, a '1' bit is added to the
|
||||
* FLASH_CRYPT_CNT value (setting the parity to 1) and the EFUSE is re-burned.
|
||||
*
|
||||
* [*] If reflashing bootloader with secure boot enabled, pre-encrypt
|
||||
* the bootloader before writing it to flash or secure boot will fail.
|
||||
*
|
||||
* [**] For this reason, if serial re-flashing a previous flashed
|
||||
* device with secure boot enabled and using FLASH_CRYPT_CNT to
|
||||
* trigger re-encryption, you must simultaneously re-flash plaintext
|
||||
* content to all partitions with the "encrypt" flag set or this
|
||||
* data will be corrupted (encrypted twice).
|
||||
*
|
||||
* @note The post-condition of this function is that all
|
||||
* partitions that should be encrypted are encrypted.
|
||||
*
|
||||
* @note Take care not to power off the device while this function
|
||||
* is running, or the partition currently being encrypted will be lost.
|
||||
*
|
||||
* @return ESP_OK if all operations succeeded, ESP_ERR_INVALID_STATE
|
||||
* if a fatal error occured during encryption of all partitions.
|
||||
*/
|
||||
esp_err_t esp_flash_encrypt_check_and_update(void);
|
||||
|
||||
|
||||
/** @brief Encrypt-in-place a block of flash sectors
|
||||
*
|
||||
* @param src_addr Source offset in flash. Should be multiple of 4096 bytes.
|
||||
* @param data_length Length of data to encrypt in bytes. Will be rounded up to next multiple of 4096 bytes.
|
||||
*
|
||||
* @return ESP_OK if all operations succeeded, ESP_ERR_FLASH_OP_FAIL
|
||||
* if SPI flash fails, ESP_ERR_FLASH_OP_TIMEOUT if flash times out.
|
||||
*/
|
||||
esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length);
|
||||
|
||||
#endif
|
||||
39
components/bootloader_support/include/esp_flash_partitions.h
Normal file
39
components/bootloader_support/include/esp_flash_partitions.h
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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 __ESP_FLASH_PARTITIONS_H
|
||||
#define __ESP_FLASH_PARTITIONS_H
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_flash_data_types.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
/* Pre-partition table fixed flash offsets */
|
||||
#define ESP_BOOTLOADER_DIGEST_OFFSET 0x0
|
||||
#define ESP_BOOTLOADER_OFFSET 0x1000 /* Offset of bootloader image. Has matching value in bootloader KConfig.projbuild file. */
|
||||
#define ESP_PARTITION_TABLE_OFFSET 0x8000 /* Offset of partition table. Has matching value in partition_table Kconfig.projbuild file. */
|
||||
|
||||
#define ESP_PARTITION_TABLE_MAX_LEN 0xC00 /* Maximum length of partition table data */
|
||||
#define ESP_PARTITION_TABLE_MAX_ENTRIES (ESP_PARTITION_TABLE_MAX_LEN / sizeof(esp_partition_info_t)) /* Maximum length of partition table data, including terminating entry */
|
||||
|
||||
/* @brief Verify the partition table (does not include verifying secure boot cryptographic signature)
|
||||
*
|
||||
* @param partition_table Pointer to at least ESP_PARTITION_TABLE_MAX_ENTRIES of potential partition table data. (ESP_PARTITION_TABLE_MAX_LEN bytes.)
|
||||
* @param log_errors Log errors if the partition table is invalid.
|
||||
* @param num_partitions If result is ESP_OK, num_partitions is updated with total number of partitions (not including terminating entry).
|
||||
*
|
||||
* @return ESP_OK on success, ESP_ERR_INVALID_STATE if partition table is not valid.
|
||||
*/
|
||||
esp_err_t esp_partition_table_basic_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions);
|
||||
|
||||
#endif
|
||||
143
components/bootloader_support/include/esp_image_format.h
Normal file
143
components/bootloader_support/include/esp_image_format.h
Normal file
@@ -0,0 +1,143 @@
|
||||
// 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 __ESP32_IMAGE_FORMAT_H
|
||||
#define __ESP32_IMAGE_FORMAT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <esp_err.h>
|
||||
|
||||
#define ESP_ERR_IMAGE_BASE 0x2000
|
||||
#define ESP_ERR_IMAGE_FLASH_FAIL (ESP_ERR_IMAGE_BASE + 1)
|
||||
#define ESP_ERR_IMAGE_INVALID (ESP_ERR_IMAGE_BASE + 2)
|
||||
|
||||
/* Support for app/bootloader image parsing
|
||||
Can be compiled as part of app or bootloader code.
|
||||
*/
|
||||
|
||||
/* SPI flash mode, used in esp_image_header_t */
|
||||
typedef enum {
|
||||
ESP_IMAGE_SPI_MODE_QIO,
|
||||
ESP_IMAGE_SPI_MODE_QOUT,
|
||||
ESP_IMAGE_SPI_MODE_DIO,
|
||||
ESP_IMAGE_SPI_MODE_DOUT,
|
||||
ESP_IMAGE_SPI_MODE_FAST_READ,
|
||||
ESP_IMAGE_SPI_MODE_SLOW_READ
|
||||
} esp_image_spi_mode_t;
|
||||
|
||||
/* SPI flash clock frequency */
|
||||
enum {
|
||||
ESP_IMAGE_SPI_SPEED_40M,
|
||||
ESP_IMAGE_SPI_SPEED_26M,
|
||||
ESP_IMAGE_SPI_SPEED_20M,
|
||||
ESP_IMAGE_SPI_SPEED_80M = 0xF
|
||||
} esp_image_spi_freq_t;
|
||||
|
||||
/* Supported SPI flash sizes */
|
||||
typedef enum {
|
||||
ESP_IMAGE_FLASH_SIZE_1MB = 0,
|
||||
ESP_IMAGE_FLASH_SIZE_2MB,
|
||||
ESP_IMAGE_FLASH_SIZE_4MB,
|
||||
ESP_IMAGE_FLASH_SIZE_8MB,
|
||||
ESP_IMAGE_FLASH_SIZE_16MB,
|
||||
ESP_IMAGE_FLASH_SIZE_MAX
|
||||
} esp_image_flash_size_t;
|
||||
|
||||
#define ESP_IMAGE_HEADER_MAGIC 0xE9
|
||||
|
||||
/* Main header of binary image */
|
||||
typedef struct {
|
||||
uint8_t magic;
|
||||
uint8_t segment_count;
|
||||
uint8_t spi_mode; /* flash read mode (esp_image_spi_mode_t as uint8_t) */
|
||||
uint8_t spi_speed: 4; /* flash frequency (esp_image_spi_freq_t as uint8_t) */
|
||||
uint8_t spi_size: 4; /* flash chip size (esp_image_flash_size_t as uint8_t) */
|
||||
uint32_t entry_addr;
|
||||
uint8_t encrypt_flag; /* encrypt flag */
|
||||
uint8_t extra_header[15]; /* ESP32 additional header, unused by second bootloader */
|
||||
} esp_image_header_t;
|
||||
|
||||
/* Header of binary image segment */
|
||||
typedef struct {
|
||||
uint32_t load_addr;
|
||||
uint32_t data_len;
|
||||
} esp_image_segment_header_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Read an ESP image header from flash.
|
||||
*
|
||||
* If encryption is enabled, data will be transparently decrypted.
|
||||
*
|
||||
* @param src_addr Address in flash to load image header. Must be 4 byte aligned.
|
||||
* @param log_errors Log error output if image header appears invalid.
|
||||
* @param[out] image_header Pointer to an esp_image_header_t struture to be filled with data. If the function fails, contents are undefined.
|
||||
*
|
||||
* @return ESP_OK if image header was loaded, ESP_ERR_IMAGE_FLASH_FAIL
|
||||
* if a SPI flash error occurs, ESP_ERR_IMAGE_INVALID if the image header
|
||||
* appears invalid.
|
||||
*/
|
||||
esp_err_t esp_image_load_header(uint32_t src_addr, bool log_errors, esp_image_header_t *image_header);
|
||||
|
||||
/**
|
||||
* @brief Read the segment header and data offset of a segment in the image.
|
||||
*
|
||||
* If encryption is enabled, data will be transparently decrypted.
|
||||
*
|
||||
* @param index Index of the segment to load information for.
|
||||
* @param src_addr Base address in flash of the image.
|
||||
* @param[in] image_header Pointer to the flash image header, already loaded by @ref esp_image_load_header().
|
||||
* @param log_errors Log errors reading the segment header.
|
||||
* @param[out] segment_header Pointer to a segment header structure to be filled with data. If the function fails, contents are undefined.
|
||||
* @param[out] segment_data_offset Pointer to the data offset of the segment.
|
||||
*
|
||||
* @return ESP_OK if segment_header & segment_data_offset were loaded successfully, ESP_ERR_IMAGE_FLASH_FAIL if a SPI flash error occurs, ESP_ERR_IMAGE_INVALID if the image header appears invalid, ESP_ERR_INVALID_ARG if the index is invalid.
|
||||
*/
|
||||
esp_err_t esp_image_load_segment_header(uint8_t index, uint32_t src_addr, const esp_image_header_t *image_header, bool log_errors, esp_image_segment_header_t *segment_header, uint32_t *segment_data_offset);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Non-cryptographically validate app image integrity. On success, length of image is provided to caller.
|
||||
*
|
||||
* If the image has a secure boot signature appended, the signature is not checked and this length is not included in the
|
||||
* output value.
|
||||
*
|
||||
* Image validation checks:
|
||||
* - Magic byte
|
||||
* - No single segment longer than 16MB
|
||||
* - Total image no longer than 16MB
|
||||
* - 8 bit image checksum is valid
|
||||
*
|
||||
* If flash encryption is enabled, the image will be tranpsarently decrypted.
|
||||
*
|
||||
* @param src_addr Offset of the start of the image in flash. Must be 4 byte aligned.
|
||||
* @param allow_decrypt If true and flash encryption is enabled, the image will be transparently decrypted.
|
||||
* @param log_errors Log errors verifying the image.
|
||||
* @param[out] length Length of the image, set to a value if the image is valid. Can be null.
|
||||
*
|
||||
* @return ESP_OK if image is valid, ESP_FAIL or ESP_ERR_IMAGE_INVALID on errors.
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_image_basic_verify(uint32_t src_addr, bool log_errors, uint32_t *length);
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t drom_addr;
|
||||
uint32_t drom_load_addr;
|
||||
uint32_t drom_size;
|
||||
uint32_t irom_addr;
|
||||
uint32_t irom_load_addr;
|
||||
uint32_t irom_size;
|
||||
} esp_image_flash_mapping_t;
|
||||
|
||||
#endif
|
||||
91
components/bootloader_support/include/esp_secure_boot.h
Normal file
91
components/bootloader_support/include/esp_secure_boot.h
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 __ESP32_SECUREBOOT_H
|
||||
#define __ESP32_SECUREBOOT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <esp_err.h>
|
||||
#include "soc/efuse_reg.h"
|
||||
|
||||
/* Support functions for secure boot features.
|
||||
|
||||
Can be compiled as part of app or bootloader code.
|
||||
*/
|
||||
|
||||
/** @brief Is secure boot currently enabled in hardware?
|
||||
*
|
||||
* Secure boot is enabled if the ABS_DONE_0 efuse is blown. This means
|
||||
* that the ROM bootloader code will only boot a verified secure
|
||||
* bootloader digest from now on.
|
||||
*
|
||||
* @return true if secure boot is enabled.
|
||||
*/
|
||||
static inline bool esp_secure_boot_enabled(void) {
|
||||
return REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_RD_ABS_DONE_0;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Enable secure boot if it is not already enabled.
|
||||
*
|
||||
* @important If this function succeeds, secure boot is permanently
|
||||
* enabled on the chip via efuse.
|
||||
*
|
||||
* @important This function is intended to be called from bootloader code only.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This function does not verify secure boot of the bootloader (the
|
||||
* ROM bootloader does this.)
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
esp_err_t esp_secure_boot_permanently_enable(void);
|
||||
|
||||
/** @brief Verify the secure boot signature (determinstic ECDSA w/ SHA256) appended to some binary data in flash.
|
||||
*
|
||||
* Public key is compiled into the calling program. See docs/security/secure-boot.rst for details.
|
||||
*
|
||||
* @param src_addr Starting offset of the data in flash.
|
||||
* @param length Length of data in bytes. Signature is appended -after- length bytes.
|
||||
*
|
||||
* If flash encryption is enabled, the image will be transparently decrypted while being verified.
|
||||
*
|
||||
* @return ESP_OK if signature is valid, ESP_ERR_INVALID_STATE if
|
||||
* signature fails, ESP_FAIL for other failures (ie can't read flash).
|
||||
*/
|
||||
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length);
|
||||
|
||||
/** @brief Secure boot verification block, on-flash data format. */
|
||||
typedef struct {
|
||||
uint32_t version;
|
||||
uint8_t signature[64];
|
||||
} esp_secure_boot_sig_block_t;
|
||||
|
||||
#define FLASH_OFFS_SECURE_BOOT_IV_DIGEST 0
|
||||
|
||||
/** @brief Secure boot IV+digest header */
|
||||
typedef struct {
|
||||
uint8_t iv[128];
|
||||
uint8_t digest[64];
|
||||
} esp_secure_boot_iv_digest_t;
|
||||
|
||||
#endif
|
||||
103
components/bootloader_support/include_priv/bootloader_flash.h
Normal file
103
components/bootloader_support/include_priv/bootloader_flash.h
Normal file
@@ -0,0 +1,103 @@
|
||||
// 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 __BOOTLOADER_FLASH_H
|
||||
#define __BOOTLOADER_FLASH_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <esp_err.h>
|
||||
#include "esp_spi_flash.h"
|
||||
|
||||
#define FLASH_SECTOR_SIZE 0x1000
|
||||
|
||||
/* Provide a Flash API for bootloader_support code,
|
||||
that can be used from bootloader or app code.
|
||||
|
||||
This header is available to source code in the bootloader &
|
||||
bootloader_support components only.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Map a region of flash to data memory
|
||||
*
|
||||
* @important In bootloader code, only one region can be bootloader_mmaped at once. The previous region must be bootloader_munmapped before another region is mapped.
|
||||
*
|
||||
* @important In app code, these functions are not thread safe.
|
||||
*
|
||||
* Call bootloader_munmap once for each successful call to bootloader_mmap.
|
||||
*
|
||||
* In esp-idf app, this function maps directly to spi_flash_mmap.
|
||||
*
|
||||
* @param offset - Starting flash offset to map to memory.
|
||||
* @param length - Length of data to map.
|
||||
*
|
||||
* @return Pointer to mapped data memory (at src_addr), or NULL
|
||||
* if an allocation error occured.
|
||||
*/
|
||||
const void *bootloader_mmap(uint32_t src_addr, uint32_t size);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Unmap a previously mapped region of flash
|
||||
*
|
||||
* Call bootloader_munmap once for each successful call to bootloader_mmap.
|
||||
*/
|
||||
void bootloader_munmap(const void *mapping);
|
||||
|
||||
/**
|
||||
* @brief Read data from Flash.
|
||||
*
|
||||
*
|
||||
* @note All of src, dest and size have to be 4-byte aligned.
|
||||
*
|
||||
* @param src source address of the data in Flash.
|
||||
* @param dest pointer to the destination buffer
|
||||
* @param size length of data
|
||||
* @param allow_decrypt If true and flash encryption is enabled, data on flash
|
||||
* will be decrypted transparently as part of the read.
|
||||
*
|
||||
* @return ESP_OK on success, ESP_ERR_FLASH_OP_FAIL on SPI failure,
|
||||
* ESP_ERR_FLASH_OP_TIMEOUT on SPI timeout.
|
||||
*/
|
||||
esp_err_t bootloader_flash_read(size_t src_addr, void *dest, size_t size, bool allow_decrypt);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Write data to Flash.
|
||||
*
|
||||
* @note All of dest_addr, src and size have to be 4-byte aligned. If write_encrypted is set, dest_addr and size must be 32-byte aligned.
|
||||
*
|
||||
* Note: In bootloader, when write_encrypted == true, the src buffer is encrypted in place.
|
||||
*
|
||||
* @param dest_addr Destination address to write in Flash.
|
||||
* @param src Pointer to the data to write to flash
|
||||
* @param size Length of data in bytes.
|
||||
* @param write_encrypted If true, data will be written encrypted on flash.
|
||||
*
|
||||
* @return ESP_OK on success, ESP_ERR_FLASH_OP_FAIL on SPI failure,
|
||||
* ESP_ERR_FLASH_OP_TIMEOUT on SPI timeout.
|
||||
*/
|
||||
esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool write_encrypted);
|
||||
|
||||
/**
|
||||
* @brief Erase the Flash sector.
|
||||
*
|
||||
* @param sector Sector number, the count starts at sector 0, 4KB per sector.
|
||||
*
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t bootloader_flash_erase_sector(size_t sector);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright 2010-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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* @brief Enable early entropy source for RNG
|
||||
*
|
||||
* Uses the SAR ADC to feed entropy into the HWRNG. The ADC is put
|
||||
* into a test mode that reads the 1.1V internal reference source and
|
||||
* feeds the LSB of data into the HWRNG.
|
||||
*
|
||||
* Can also be used from app code early during operation, if entropy
|
||||
* is required before WiFi stack is initialised. Call this function
|
||||
* from app code only if WiFi/BT are not yet enabled and I2S and SAR
|
||||
* ADC are not in use.
|
||||
*
|
||||
* Call bootloader_random_disable() when done.
|
||||
*/
|
||||
void bootloader_random_enable(void);
|
||||
|
||||
/**
|
||||
* @brief Disable early entropy source for RNG
|
||||
*
|
||||
* Disables SAR ADC source and resets the I2S hardware.
|
||||
*
|
||||
*/
|
||||
void bootloader_random_disable(void);
|
||||
|
||||
/**
|
||||
* @brief Fill buffer with 'length' random bytes
|
||||
*
|
||||
* @param buffer Pointer to buffer
|
||||
* @param length This many bytes of random data will be copied to buffer
|
||||
*/
|
||||
void bootloader_fill_random(void *buffer, size_t length);
|
||||
241
components/bootloader_support/src/bootloader_flash.c
Normal file
241
components/bootloader_support/src/bootloader_flash.c
Normal file
@@ -0,0 +1,241 @@
|
||||
// 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 <stddef.h>
|
||||
|
||||
#include <bootloader_flash.h>
|
||||
#include <esp_log.h>
|
||||
#include <esp_spi_flash.h> /* including in bootloader for error values */
|
||||
#include <esp_flash_encrypt.h>
|
||||
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
/* Normal app version maps to esp_spi_flash.h operations...
|
||||
*/
|
||||
static const char *TAG = "bootloader_mmap";
|
||||
|
||||
static spi_flash_mmap_memory_t map;
|
||||
|
||||
const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
|
||||
{
|
||||
if (map) {
|
||||
ESP_LOGE(TAG, "tried to bootloader_mmap twice");
|
||||
return NULL; /* existing mapping in use... */
|
||||
}
|
||||
const void *result = NULL;
|
||||
esp_err_t err = spi_flash_mmap(src_addr, size, SPI_FLASH_MMAP_DATA, &result, &map);
|
||||
if (err != ESP_OK) {
|
||||
result = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void bootloader_munmap(const void *mapping)
|
||||
{
|
||||
if(mapping && map) {
|
||||
spi_flash_munmap(map);
|
||||
}
|
||||
map = 0;
|
||||
}
|
||||
|
||||
esp_err_t bootloader_flash_read(size_t src, void *dest, size_t size, bool allow_decrypt)
|
||||
{
|
||||
if (allow_decrypt && esp_flash_encryption_enabled()) {
|
||||
return spi_flash_read_encrypted(src, dest, size);
|
||||
} else {
|
||||
return spi_flash_read(src, dest, size);
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool write_encrypted)
|
||||
{
|
||||
if (write_encrypted) {
|
||||
return spi_flash_write_encrypted(dest_addr, src, size);
|
||||
} else {
|
||||
return spi_flash_write(dest_addr, src, size);
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t bootloader_flash_erase_sector(size_t sector)
|
||||
{
|
||||
return spi_flash_erase_sector(sector);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Bootloader version, uses ROM functions only */
|
||||
#include <soc/dport_reg.h>
|
||||
#include <rom/spi_flash.h>
|
||||
#include <rom/cache.h>
|
||||
|
||||
static const char *TAG = "bootloader_flash";
|
||||
|
||||
/* Use first 50 blocks in MMU for bootloader_mmap,
|
||||
50th block for bootloader_flash_read
|
||||
*/
|
||||
#define MMU_BLOCK0_VADDR 0x3f400000
|
||||
#define MMU_BLOCK50_VADDR 0x3f720000
|
||||
#define MMU_FLASH_MASK 0xffff0000
|
||||
#define MMU_BLOCK_SIZE 0x00010000
|
||||
|
||||
static bool mapped;
|
||||
|
||||
static uint32_t current_read_mapping = UINT32_MAX;
|
||||
|
||||
const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
|
||||
{
|
||||
if (mapped) {
|
||||
ESP_LOGE(TAG, "tried to bootloader_mmap twice");
|
||||
return NULL; /* can't map twice */
|
||||
}
|
||||
if (size > 0x320000) {
|
||||
/* Allow mapping up to 50 of the 51 available MMU blocks (last one used for reads) */
|
||||
ESP_LOGE(TAG, "bootloader_mmap excess size %x", size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t src_addr_aligned = src_addr & MMU_FLASH_MASK;
|
||||
uint32_t count = (size + (src_addr - src_addr_aligned) + 0xffff) / MMU_BLOCK_SIZE;
|
||||
Cache_Read_Disable(0);
|
||||
Cache_Flush(0);
|
||||
ESP_LOGD(TAG, "mmu set paddr=%08x count=%d", src_addr_aligned, count );
|
||||
cache_flash_mmu_set( 0, 0, MMU_BLOCK0_VADDR, src_addr_aligned, 64, count );
|
||||
Cache_Read_Enable( 0 );
|
||||
|
||||
mapped = true;
|
||||
|
||||
return (void *)(MMU_BLOCK0_VADDR + (src_addr - src_addr_aligned));
|
||||
}
|
||||
|
||||
void bootloader_munmap(const void *mapping)
|
||||
{
|
||||
if (mapped) {
|
||||
/* Full MMU reset */
|
||||
Cache_Read_Disable(0);
|
||||
Cache_Flush(0);
|
||||
mmu_init(0);
|
||||
mapped = false;
|
||||
current_read_mapping = UINT32_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t spi_to_esp_err(SpiFlashOpResult r)
|
||||
{
|
||||
switch(r) {
|
||||
case SPI_FLASH_RESULT_OK:
|
||||
return ESP_OK;
|
||||
case SPI_FLASH_RESULT_ERR:
|
||||
return ESP_ERR_FLASH_OP_FAIL;
|
||||
case SPI_FLASH_RESULT_TIMEOUT:
|
||||
return ESP_ERR_FLASH_OP_TIMEOUT;
|
||||
default:
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t bootloader_flash_read_no_decrypt(size_t src_addr, void *dest, size_t size)
|
||||
{
|
||||
Cache_Read_Disable(0);
|
||||
Cache_Flush(0);
|
||||
SpiFlashOpResult r = SPIRead(src_addr, dest, size);
|
||||
Cache_Read_Enable(0);
|
||||
|
||||
return spi_to_esp_err(r);
|
||||
}
|
||||
|
||||
static esp_err_t bootloader_flash_read_allow_decrypt(size_t src_addr, void *dest, size_t size)
|
||||
{
|
||||
uint32_t *dest_words = (uint32_t *)dest;
|
||||
|
||||
/* Use the 51st MMU mapping to read from flash in 64KB blocks.
|
||||
(MMU will transparently decrypt if encryption is enabled.)
|
||||
*/
|
||||
for (int word = 0; word < size / 4; word++) {
|
||||
uint32_t word_src = src_addr + word * 4; /* Read this offset from flash */
|
||||
uint32_t map_at = word_src & MMU_FLASH_MASK; /* Map this 64KB block from flash */
|
||||
uint32_t *map_ptr;
|
||||
if (map_at != current_read_mapping) {
|
||||
/* Move the 64KB mmu mapping window to fit map_at */
|
||||
Cache_Read_Disable(0);
|
||||
Cache_Flush(0);
|
||||
ESP_LOGD(TAG, "mmu set block paddr=0x%08x (was 0x%08x)", map_at, current_read_mapping);
|
||||
int e = cache_flash_mmu_set(0, 0, MMU_BLOCK50_VADDR, map_at, 64, 1);
|
||||
if (e != 0) {
|
||||
ESP_LOGE(TAG, "cache_flash_mmu_set failed: %d\n", e);
|
||||
Cache_Read_Enable(0);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
current_read_mapping = map_at;
|
||||
Cache_Read_Enable(0);
|
||||
}
|
||||
map_ptr = (uint32_t *)(MMU_BLOCK50_VADDR + (word_src - map_at));
|
||||
dest_words[word] = *map_ptr;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t bootloader_flash_read(size_t src_addr, void *dest, size_t size, bool allow_decrypt)
|
||||
{
|
||||
if (src_addr & 3) {
|
||||
ESP_LOGE(TAG, "bootloader_flash_read src_addr 0x%x not 4-byte aligned", src_addr);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (size & 3) {
|
||||
ESP_LOGE(TAG, "bootloader_flash_read size 0x%x not 4-byte aligned", size);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if ((intptr_t)dest & 3) {
|
||||
ESP_LOGE(TAG, "bootloader_flash_read dest 0x%x not 4-byte aligned", (intptr_t)dest);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (allow_decrypt) {
|
||||
return bootloader_flash_read_allow_decrypt(src_addr, dest, size);
|
||||
} else {
|
||||
return bootloader_flash_read_no_decrypt(src_addr, dest, size);
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t bootloader_flash_write(size_t dest_addr, void *src, size_t size, bool write_encrypted)
|
||||
{
|
||||
esp_err_t err;
|
||||
size_t alignment = write_encrypted ? 32 : 4;
|
||||
if ((dest_addr % alignment) != 0) {
|
||||
ESP_LOGE(TAG, "bootloader_flash_write dest_addr 0x%x not %d-byte aligned", dest_addr, alignment);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if ((size % alignment) != 0) {
|
||||
ESP_LOGE(TAG, "bootloader_flash_write size 0x%x not %d-byte aligned", size, alignment);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
if (((intptr_t)src % 4) != 0) {
|
||||
ESP_LOGE(TAG, "bootloader_flash_write src 0x%x not 4 byte aligned", (intptr_t)src);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
err = spi_to_esp_err(SPIUnlock());
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (write_encrypted) {
|
||||
return spi_to_esp_err(SPI_Encrypt_Write(dest_addr, src, size));
|
||||
} else {
|
||||
return spi_to_esp_err(SPIWrite(dest_addr, src, size));
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t bootloader_flash_erase_sector(size_t sector)
|
||||
{
|
||||
return spi_to_esp_err(SPIEraseSector(sector));
|
||||
}
|
||||
|
||||
#endif
|
||||
147
components/bootloader_support/src/bootloader_random.c
Normal file
147
components/bootloader_support/src/bootloader_random.c
Normal file
@@ -0,0 +1,147 @@
|
||||
// Copyright 2010-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 "bootloader_random.h"
|
||||
#include "soc/cpu.h"
|
||||
#include "soc/wdev_reg.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/sens_reg.h"
|
||||
#include "soc/syscon_reg.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/i2s_reg.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
#include "esp_system.h"
|
||||
#endif
|
||||
|
||||
const char *TAG = "boot_rng";
|
||||
|
||||
void bootloader_fill_random(void *buffer, size_t length)
|
||||
{
|
||||
uint8_t *buffer_bytes = (uint8_t *)buffer;
|
||||
uint32_t random;
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
uint32_t start, now;
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (i == 0 || i % 4 == 0) { /* redundant check is for a compiler warning */
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
/* in bootloader with ADC feeding HWRNG, we accumulate 1
|
||||
bit of entropy per 40 APB cycles (==80 CPU cycles.)
|
||||
|
||||
To avoid reading the entire RNG hardware state out
|
||||
as-is, we repeatedly read the RNG register and XOR all
|
||||
values.
|
||||
*/
|
||||
random = REG_READ(WDEV_RND_REG);
|
||||
RSR(CCOUNT, start);
|
||||
do {
|
||||
random ^= REG_READ(WDEV_RND_REG);
|
||||
RSR(CCOUNT, now);
|
||||
} while(now - start < 80*32*2); /* extra factor of 2 is precautionary */
|
||||
#else
|
||||
random = esp_random();
|
||||
#endif
|
||||
}
|
||||
|
||||
buffer_bytes[i] = random >> ((i % 4) * 8);
|
||||
}
|
||||
}
|
||||
|
||||
void bootloader_random_enable(void)
|
||||
{
|
||||
/* Ensure the hardware RNG is enabled following a soft reset. This should always be the case already (this clock is
|
||||
never disabled while the CPU is running), this is a "belts and braces" type check.
|
||||
*/
|
||||
SET_PERI_REG_MASK(DPORT_WIFI_CLK_EN_REG, DPORT_WIFI_CLK_RNG_EN);
|
||||
|
||||
/* Enable SAR ADC in test mode to feed ADC readings of the 1.1V
|
||||
reference via I2S into the RNG entropy input.
|
||||
|
||||
Note: I2S requires the PLL to be running, so the call to rtc_set_cpu_freq(CPU_80M)
|
||||
in early bootloader startup must have been made.
|
||||
*/
|
||||
SET_PERI_REG_BITS(RTC_CNTL_TEST_MUX_REG, RTC_CNTL_DTEST_RTC, 2, RTC_CNTL_DTEST_RTC_S);
|
||||
SET_PERI_REG_MASK(RTC_CNTL_TEST_MUX_REG, RTC_CNTL_ENT_RTC);
|
||||
SET_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_SAR2_EN_TEST);
|
||||
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_ULP_CP_FORCE_START_TOP);
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_ULP_CP_START_TOP);
|
||||
// Test pattern configuration byte 0xAD:
|
||||
//--[7:4] channel_sel: 10-->en_test
|
||||
//--[3:2] bit_width : 3-->12bit
|
||||
//--[1:0] atten : 1-->3dB attenuation
|
||||
WRITE_PERI_REG(SYSCON_SARADC_SAR2_PATT_TAB1_REG, 0xADADADAD);
|
||||
WRITE_PERI_REG(SYSCON_SARADC_SAR2_PATT_TAB2_REG, 0xADADADAD);
|
||||
WRITE_PERI_REG(SYSCON_SARADC_SAR2_PATT_TAB3_REG, 0xADADADAD);
|
||||
WRITE_PERI_REG(SYSCON_SARADC_SAR2_PATT_TAB4_REG, 0xADADADAD);
|
||||
|
||||
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 3, SENS_FORCE_XPD_SAR_S);
|
||||
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DIG_FORCE);
|
||||
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DIG_FORCE);
|
||||
SET_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR2_MUX);
|
||||
SET_PERI_REG_BITS(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR_CLK_DIV, 4, SYSCON_SARADC_SAR_CLK_DIV_S);
|
||||
|
||||
SET_PERI_REG_BITS(SYSCON_SARADC_FSM_REG, SYSCON_SARADC_RSTB_WAIT, 8, SYSCON_SARADC_RSTB_WAIT_S); /* was 1 */
|
||||
SET_PERI_REG_BITS(SYSCON_SARADC_FSM_REG, SYSCON_SARADC_START_WAIT, 10, SYSCON_SARADC_START_WAIT_S);
|
||||
SET_PERI_REG_BITS(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_WORK_MODE, 0, SYSCON_SARADC_WORK_MODE_S);
|
||||
SET_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR_SEL);
|
||||
CLEAR_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_DATA_SAR_SEL);
|
||||
|
||||
SET_PERI_REG_BITS(I2S_SAMPLE_RATE_CONF_REG(0), I2S_RX_BCK_DIV_NUM, 20, I2S_RX_BCK_DIV_NUM_S);
|
||||
|
||||
SET_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG,SYSCON_SARADC_DATA_TO_I2S);
|
||||
|
||||
CLEAR_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_CAMERA_EN);
|
||||
SET_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_LCD_EN);
|
||||
SET_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_DATA_ENABLE);
|
||||
SET_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_DATA_ENABLE_TEST_EN);
|
||||
SET_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_START);
|
||||
}
|
||||
|
||||
void bootloader_random_disable(void)
|
||||
{
|
||||
/* Disable i2s clock */
|
||||
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_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);
|
||||
|
||||
/* Restore SYSCON mode registers */
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DIG_FORCE);
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DIG_FORCE);
|
||||
|
||||
/* Restore SAR ADC mode */
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_SAR2_EN_TEST);
|
||||
CLEAR_PERI_REG_MASK(SYSCON_SARADC_CTRL_REG, SYSCON_SARADC_SAR2_MUX
|
||||
| SYSCON_SARADC_SAR_SEL | SYSCON_SARADC_DATA_TO_I2S);
|
||||
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 0, SENS_FORCE_XPD_SAR_S);
|
||||
SET_PERI_REG_BITS(SYSCON_SARADC_FSM_REG, SYSCON_SARADC_START_WAIT, 8, SYSCON_SARADC_START_WAIT_S);
|
||||
|
||||
/* Reset i2s peripheral */
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
|
||||
|
||||
/* Disable pull supply voltage to SAR ADC */
|
||||
CLEAR_PERI_REG_MASK(RTC_CNTL_TEST_MUX_REG, RTC_CNTL_ENT_RTC);
|
||||
SET_PERI_REG_BITS(RTC_CNTL_TEST_MUX_REG, RTC_CNTL_DTEST_RTC, 0, RTC_CNTL_DTEST_RTC_S);
|
||||
}
|
||||
47
components/bootloader_support/src/efuse.c
Normal file
47
components/bootloader_support/src/efuse.c
Normal file
@@ -0,0 +1,47 @@
|
||||
// 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 "esp_efuse.h"
|
||||
|
||||
#define EFUSE_CONF_WRITE 0x5A5A /* efuse_pgm_op_ena, force no rd/wr disable */
|
||||
#define EFUSE_CONF_READ 0x5AA5 /* efuse_read_op_ena, release force */
|
||||
|
||||
#define EFUSE_CMD_PGM 0x02
|
||||
#define EFUSE_CMD_READ 0x01
|
||||
|
||||
void esp_efuse_burn_new_values(void)
|
||||
{
|
||||
REG_WRITE(EFUSE_CONF_REG, EFUSE_CONF_WRITE);
|
||||
REG_WRITE(EFUSE_CMD_REG, EFUSE_CMD_PGM);
|
||||
while (REG_READ(EFUSE_CMD_REG) != 0) {
|
||||
}
|
||||
REG_WRITE(EFUSE_CONF_REG, EFUSE_CONF_READ);
|
||||
REG_WRITE(EFUSE_CMD_REG, EFUSE_CMD_READ);
|
||||
while (REG_READ(EFUSE_CMD_REG) != 0) {
|
||||
}
|
||||
esp_efuse_reset();
|
||||
}
|
||||
|
||||
void esp_efuse_reset(void)
|
||||
{
|
||||
REG_WRITE(EFUSE_CONF_REG, EFUSE_CONF_READ);
|
||||
const uint32_t block_start[4] = { EFUSE_BLK0_WDATA0_REG, EFUSE_BLK1_WDATA0_REG,
|
||||
EFUSE_BLK2_WDATA0_REG, EFUSE_BLK3_WDATA0_REG };
|
||||
const uint32_t block_end[4] = { EFUSE_BLK0_WDATA6_REG, EFUSE_BLK1_WDATA7_REG,
|
||||
EFUSE_BLK2_WDATA7_REG, EFUSE_BLK3_WDATA7_REG };
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (uint32_t r = block_start[i]; r <= block_end[i]; r+= 4) {
|
||||
REG_WRITE(r, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
174
components/bootloader_support/src/esp_image_format.c
Normal file
174
components/bootloader_support/src/esp_image_format.c
Normal file
@@ -0,0 +1,174 @@
|
||||
// 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 <string.h>
|
||||
|
||||
#include <esp_image_format.h>
|
||||
#include <esp_log.h>
|
||||
#include <bootloader_flash.h>
|
||||
|
||||
static const char *TAG = "esp_image";
|
||||
|
||||
#define SIXTEEN_MB 0x1000000
|
||||
#define ESP_ROM_CHECKSUM_INITIAL 0xEF
|
||||
|
||||
esp_err_t esp_image_load_header(uint32_t src_addr, bool log_errors, esp_image_header_t *image_header)
|
||||
{
|
||||
esp_err_t err;
|
||||
ESP_LOGD(TAG, "reading image header @ 0x%x", src_addr);
|
||||
|
||||
err = bootloader_flash_read(src_addr, image_header, sizeof(esp_image_header_t), true);
|
||||
|
||||
if (err == ESP_OK) {
|
||||
if (image_header->magic != ESP_IMAGE_HEADER_MAGIC) {
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "image at 0x%x has invalid magic byte", src_addr);
|
||||
}
|
||||
err = ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
if (log_errors) {
|
||||
if (image_header->spi_mode > ESP_IMAGE_SPI_MODE_SLOW_READ) {
|
||||
ESP_LOGW(TAG, "image at 0x%x has invalid SPI mode %d", src_addr, image_header->spi_mode);
|
||||
}
|
||||
if (image_header->spi_speed > ESP_IMAGE_SPI_SPEED_80M) {
|
||||
ESP_LOGW(TAG, "image at 0x%x has invalid SPI speed %d", src_addr, image_header->spi_speed);
|
||||
}
|
||||
if (image_header->spi_size > ESP_IMAGE_FLASH_SIZE_MAX) {
|
||||
ESP_LOGW(TAG, "image at 0x%x has invalid SPI size %d", src_addr, image_header->spi_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (err != ESP_OK) {
|
||||
bzero(image_header, sizeof(esp_image_header_t));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_image_load_segment_header(uint8_t index, uint32_t src_addr, const esp_image_header_t *image_header, bool log_errors, esp_image_segment_header_t *segment_header, uint32_t *segment_data_offset)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
uint32_t next_addr = src_addr + sizeof(esp_image_header_t);
|
||||
|
||||
if(index >= image_header->segment_count) {
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "index %d higher than segment count %d", index, image_header->segment_count);
|
||||
}
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
for(int i = 0; i <= index && err == ESP_OK; i++) {
|
||||
ESP_LOGV(TAG, "loading segment header %d at offset 0x%x", i, next_addr);
|
||||
err = bootloader_flash_read(next_addr, segment_header, sizeof(esp_image_segment_header_t), true);
|
||||
if (err == ESP_OK) {
|
||||
if ((segment_header->data_len & 3) != 0
|
||||
|| segment_header->data_len >= SIXTEEN_MB) {
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "invalid segment length 0x%x", segment_header->data_len);
|
||||
}
|
||||
err = ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
next_addr += sizeof(esp_image_segment_header_t);
|
||||
ESP_LOGV(TAG, "segment data length 0x%x data starts 0x%x", segment_header->data_len, next_addr);
|
||||
*segment_data_offset = next_addr;
|
||||
next_addr += segment_header->data_len;
|
||||
}
|
||||
}
|
||||
|
||||
if (err != ESP_OK) {
|
||||
*segment_data_offset = 0;
|
||||
bzero(segment_header, sizeof(esp_image_segment_header_t));
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
esp_err_t esp_image_basic_verify(uint32_t src_addr, bool log_errors, uint32_t *p_length)
|
||||
{
|
||||
esp_err_t err;
|
||||
uint8_t buf[128];
|
||||
uint8_t checksum = ESP_ROM_CHECKSUM_INITIAL;
|
||||
esp_image_header_t image_header;
|
||||
esp_image_segment_header_t segment_header = { 0 };
|
||||
uint32_t segment_data_offs = 0;
|
||||
uint32_t end_addr;
|
||||
uint32_t length;
|
||||
|
||||
if (p_length != NULL) {
|
||||
*p_length = 0;
|
||||
}
|
||||
|
||||
err = esp_image_load_header(src_addr, log_errors, &image_header);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "reading %d image segments", image_header.segment_count);
|
||||
|
||||
/* Checksum each segment's data */
|
||||
for (int i = 0; i < image_header.segment_count; i++) {
|
||||
err = esp_image_load_segment_header(i, src_addr, &image_header, log_errors,
|
||||
&segment_header, &segment_data_offs);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
for (int i = 0; i < segment_header.data_len; i += sizeof(buf)) {
|
||||
err = bootloader_flash_read(segment_data_offs + i, buf, sizeof(buf), true);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
for (int j = 0; j < sizeof(buf) && i + j < segment_header.data_len; j++) {
|
||||
checksum ^= buf[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* End of image, verify checksum */
|
||||
end_addr = segment_data_offs + segment_header.data_len;
|
||||
|
||||
if (end_addr < src_addr) {
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "image offset has wrapped");
|
||||
}
|
||||
return ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
|
||||
length = end_addr - src_addr;
|
||||
if (length >= SIXTEEN_MB) {
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "invalid total length 0x%x", length);
|
||||
}
|
||||
return ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
|
||||
/* image padded to next full 16 byte block, with checksum byte at very end */
|
||||
ESP_LOGV(TAG, "unpadded image length 0x%x", length);
|
||||
length += 16; /* always pad by at least 1 byte */
|
||||
length = length - (length % 16);
|
||||
ESP_LOGV(TAG, "padded image length 0x%x", length);
|
||||
ESP_LOGD(TAG, "reading checksum block at 0x%x", src_addr + length - 16);
|
||||
bootloader_flash_read(src_addr + length - 16, buf, 16, true);
|
||||
if (checksum != buf[15]) {
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "checksum failed. Calculated 0x%x read 0x%x",
|
||||
checksum, buf[15]);
|
||||
}
|
||||
return ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
|
||||
if (p_length != NULL) {
|
||||
*p_length = length;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
339
components/bootloader_support/src/flash_encrypt.c
Normal file
339
components/bootloader_support/src/flash_encrypt.c
Normal file
@@ -0,0 +1,339 @@
|
||||
// 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 <strings.h>
|
||||
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_random.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_flash_partitions.h"
|
||||
#include "esp_flash_data_types.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_log.h"
|
||||
#include "rom/secure_boot.h"
|
||||
|
||||
#include "rom/cache.h"
|
||||
#include "rom/spi_flash.h" /* TODO: Remove this */
|
||||
|
||||
static const char *TAG = "flash_encrypt";
|
||||
|
||||
/* Static functions for stages of flash encryption */
|
||||
static esp_err_t initialise_flash_encryption(void);
|
||||
static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_crypt_wr_dis);
|
||||
static esp_err_t encrypt_bootloader();
|
||||
static esp_err_t encrypt_and_load_partition_table(esp_partition_info_t *partition_table, int *num_partitions);
|
||||
static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partition);
|
||||
|
||||
esp_err_t esp_flash_encrypt_check_and_update(void)
|
||||
{
|
||||
uint32_t efuse_blk0 = REG_READ(EFUSE_BLK0_RDATA0_REG);
|
||||
ESP_LOGV(TAG, "efuse_blk0 raw value %08x", efuse_blk0);
|
||||
uint32_t flash_crypt_cnt = (efuse_blk0 & EFUSE_RD_FLASH_CRYPT_CNT_M) >> EFUSE_RD_FLASH_CRYPT_CNT_S;
|
||||
bool flash_crypt_wr_dis = efuse_blk0 & EFUSE_WR_DIS_FLASH_CRYPT_CNT;
|
||||
ESP_LOGV(TAG, "efuse FLASH_CRYPT_CNT 0x%x WR_DIS_FLASH_CRYPT_CNT 0x%x", flash_crypt_cnt, flash_crypt_wr_dis);
|
||||
|
||||
if (__builtin_parity(flash_crypt_cnt) == 1) {
|
||||
/* Flash is already encrypted */
|
||||
int left = (7 - __builtin_popcount(flash_crypt_cnt)) / 2;
|
||||
if (flash_crypt_wr_dis) {
|
||||
left = 0; /* can't update FLASH_CRYPT_CNT, no more flashes */
|
||||
}
|
||||
ESP_LOGI(TAG, "flash encryption is enabled (%d plaintext flashes left)", left);
|
||||
return ESP_OK;
|
||||
}
|
||||
else {
|
||||
/* Flash is not encrypted, so encrypt it! */
|
||||
return encrypt_flash_contents(flash_crypt_cnt, flash_crypt_wr_dis);
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t initialise_flash_encryption(void)
|
||||
{
|
||||
/* Before first flash encryption pass, need to initialise key & crypto config */
|
||||
|
||||
/* Generate key */
|
||||
uint32_t dis_reg = REG_READ(EFUSE_BLK0_RDATA0_REG);
|
||||
bool efuse_key_read_protected = dis_reg & EFUSE_RD_DIS_BLK1;
|
||||
bool efuse_key_write_protected = dis_reg & EFUSE_WR_DIS_BLK1;
|
||||
if (efuse_key_read_protected == false
|
||||
&& efuse_key_write_protected == false
|
||||
&& REG_READ(EFUSE_BLK1_RDATA0_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK1_RDATA1_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK1_RDATA2_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK1_RDATA3_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK1_RDATA4_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK1_RDATA5_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK1_RDATA6_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK1_RDATA7_REG) == 0) {
|
||||
ESP_LOGI(TAG, "Generating new flash encryption key...");
|
||||
uint32_t buf[8];
|
||||
bootloader_fill_random(buf, sizeof(buf));
|
||||
for (int i = 0; i < 8; i++) {
|
||||
ESP_LOGV(TAG, "EFUSE_BLK1_WDATA%d_REG = 0x%08x", i, buf[i]);
|
||||
REG_WRITE(EFUSE_BLK1_WDATA0_REG + 4*i, buf[i]);
|
||||
}
|
||||
bzero(buf, sizeof(buf));
|
||||
esp_efuse_burn_new_values();
|
||||
|
||||
ESP_LOGI(TAG, "Read & write protecting new key...");
|
||||
REG_WRITE(EFUSE_BLK0_WDATA0_REG, EFUSE_WR_DIS_BLK1 | EFUSE_RD_DIS_BLK1);
|
||||
esp_efuse_burn_new_values();
|
||||
} else {
|
||||
|
||||
if(!(efuse_key_read_protected && efuse_key_write_protected)) {
|
||||
ESP_LOGE(TAG, "Flash encryption key has to be either unset or both read and write protected");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
ESP_LOGW(TAG, "Using pre-loaded flash encryption key in EFUSE block 1");
|
||||
}
|
||||
/* CRYPT_CONFIG determines which bits of the AES block key are XORed
|
||||
with bits from the flash address, to provide the key tweak.
|
||||
|
||||
CRYPT_CONFIG == 0 is effectively AES ECB mode (NOT SUPPORTED)
|
||||
|
||||
For now this is hardcoded to XOR all 256 bits of the key.
|
||||
|
||||
If you need to override it, you can pre-burn this efuse to the
|
||||
desired value and then write-protect it, in which case this
|
||||
operation does nothing. Please note this is not recommended!
|
||||
*/
|
||||
ESP_LOGI(TAG, "Setting CRYPT_CONFIG efuse to 0xF");
|
||||
REG_WRITE(EFUSE_BLK0_WDATA5_REG, EFUSE_FLASH_CRYPT_CONFIG_M);
|
||||
esp_efuse_burn_new_values();
|
||||
|
||||
uint32_t new_wdata6 = 0;
|
||||
#ifndef CONFIG_FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_ENCRYPT
|
||||
ESP_LOGI(TAG, "Disable UART bootloader encryption...");
|
||||
new_wdata6 |= EFUSE_DISABLE_DL_ENCRYPT;
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling UART bootloader encryption");
|
||||
#endif
|
||||
#ifndef CONFIG_FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_DECRYPT
|
||||
ESP_LOGI(TAG, "Disable UART bootloader decryption...");
|
||||
new_wdata6 |= EFUSE_DISABLE_DL_DECRYPT;
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling UART bootloader decryption - SECURITY COMPROMISED");
|
||||
#endif
|
||||
#ifndef CONFIG_FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_CACHE
|
||||
ESP_LOGI(TAG, "Disable UART bootloader MMU cache...");
|
||||
new_wdata6 |= EFUSE_DISABLE_DL_CACHE;
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling UART bootloader MMU cache - SECURITY COMPROMISED");
|
||||
#endif
|
||||
#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG
|
||||
ESP_LOGI(TAG, "Disable JTAG...");
|
||||
new_wdata6 |= EFUSE_RD_DISABLE_JTAG;
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
if (new_wdata6 != 0) {
|
||||
REG_WRITE(EFUSE_BLK0_WDATA6_REG, new_wdata6);
|
||||
esp_efuse_burn_new_values();
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Encrypt all flash data that should be encrypted */
|
||||
static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_crypt_wr_dis)
|
||||
{
|
||||
esp_err_t err;
|
||||
esp_partition_info_t partition_table[ESP_PARTITION_TABLE_MAX_ENTRIES];
|
||||
int num_partitions;
|
||||
|
||||
/* 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) {
|
||||
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;
|
||||
}
|
||||
|
||||
if (flash_crypt_cnt == 0) {
|
||||
/* Very first flash of encrypted data: generate keys, etc. */
|
||||
err = initialise_flash_encryption();
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
err = encrypt_bootloader();
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
err = encrypt_and_load_partition_table(partition_table, &num_partitions);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Now iterate the just-loaded partition table, looking for entries to encrypt
|
||||
*/
|
||||
|
||||
/* Go through each partition and encrypt if necessary */
|
||||
for (int i = 0; i < num_partitions; i++) {
|
||||
err = encrypt_partition(i, &partition_table[i]);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
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);
|
||||
esp_efuse_burn_new_values();
|
||||
|
||||
ESP_LOGI(TAG, "Flash encryption completed");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t encrypt_bootloader()
|
||||
{
|
||||
esp_err_t err;
|
||||
uint32_t image_length;
|
||||
/* Check for plaintext bootloader */
|
||||
if (esp_image_basic_verify(ESP_BOOTLOADER_OFFSET, false, &image_length) == ESP_OK) {
|
||||
ESP_LOGD(TAG, "bootloader is plaintext. Encrypting...");
|
||||
err = esp_flash_encrypt_region(ESP_BOOTLOADER_OFFSET, image_length);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to encrypt bootloader in place: 0x%x", err);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ESP_LOGW(TAG, "no valid bootloader was found");
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t encrypt_and_load_partition_table(esp_partition_info_t *partition_table, int *num_partitions)
|
||||
{
|
||||
esp_err_t err;
|
||||
/* Check for plaintext partition table */
|
||||
err = bootloader_flash_read(ESP_PARTITION_TABLE_OFFSET, partition_table, ESP_PARTITION_TABLE_MAX_LEN, false);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to read partition table data");
|
||||
return err;
|
||||
}
|
||||
if (esp_partition_table_basic_verify(partition_table, false, num_partitions) == ESP_OK) {
|
||||
ESP_LOGD(TAG, "partition table is plaintext. Encrypting...");
|
||||
esp_err_t err = esp_flash_encrypt_region(ESP_PARTITION_TABLE_OFFSET,
|
||||
FLASH_SECTOR_SIZE);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to encrypt partition table in place. %x", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ESP_LOGE(TAG, "Failed to read partition table data - not plaintext?");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
/* Valid partition table loded */
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
static esp_err_t encrypt_partition(int index, const esp_partition_info_t *partition)
|
||||
{
|
||||
esp_err_t err;
|
||||
uint32_t image_len = partition->pos.size;
|
||||
bool should_encrypt = (partition->flags & PART_FLAG_ENCRYPTED);
|
||||
|
||||
if (partition->type == PART_TYPE_APP) {
|
||||
/* check if the partition holds an unencrypted app */
|
||||
if (esp_image_basic_verify(partition->pos.offset, false, &image_len) == ESP_OK) {
|
||||
if(image_len > partition->pos.size) {
|
||||
ESP_LOGE(TAG, "partition entry %d has image longer than partition (%d vs %d)", index, image_len, partition->pos.size);
|
||||
should_encrypt = false;
|
||||
} else {
|
||||
should_encrypt = true;
|
||||
}
|
||||
} else {
|
||||
should_encrypt = false;
|
||||
}
|
||||
} else if (partition->type == PART_TYPE_DATA && partition->subtype == PART_SUBTYPE_DATA_OTA) {
|
||||
/* check if we have ota data partition and the partition should be encrypted unconditionally */
|
||||
should_encrypt = true;
|
||||
}
|
||||
|
||||
if (!should_encrypt) {
|
||||
return ESP_OK;
|
||||
}
|
||||
else {
|
||||
/* should_encrypt */
|
||||
ESP_LOGI(TAG, "Encrypting partition %d at offset 0x%x...", index, partition->pos.offset);
|
||||
|
||||
err = esp_flash_encrypt_region(partition->pos.offset, partition->pos.size);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to encrypt partition %d", index);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_flash_encrypt_region(uint32_t src_addr, size_t data_length)
|
||||
{
|
||||
esp_err_t err;
|
||||
uint32_t buf[FLASH_SECTOR_SIZE / sizeof(uint32_t)];
|
||||
|
||||
if (src_addr % FLASH_SECTOR_SIZE != 0) {
|
||||
ESP_LOGE(TAG, "esp_flash_encrypt_region bad src_addr 0x%x",src_addr);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < data_length; i += FLASH_SECTOR_SIZE) {
|
||||
uint32_t sec_start = i + src_addr;
|
||||
err = bootloader_flash_read(sec_start, buf, FLASH_SECTOR_SIZE, false);
|
||||
if (err != ESP_OK) {
|
||||
goto flash_failed;
|
||||
}
|
||||
err = bootloader_flash_erase_sector(sec_start / FLASH_SECTOR_SIZE);
|
||||
if (err != ESP_OK) {
|
||||
goto flash_failed;
|
||||
}
|
||||
err = bootloader_flash_write(sec_start, buf, FLASH_SECTOR_SIZE, true);
|
||||
if (err != ESP_OK) {
|
||||
goto flash_failed;
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
|
||||
flash_failed:
|
||||
ESP_LOGE(TAG, "flash operation failed: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
60
components/bootloader_support/src/flash_partitions.c
Normal file
60
components/bootloader_support/src/flash_partitions.c
Normal file
@@ -0,0 +1,60 @@
|
||||
// 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 "esp_flash_partitions.h"
|
||||
#include "esp_log.h"
|
||||
#include "rom/spi_flash.h"
|
||||
|
||||
static const char *TAG = "flash_parts";
|
||||
|
||||
esp_err_t esp_partition_table_basic_verify(const esp_partition_info_t *partition_table, bool log_errors, int *num_partitions)
|
||||
{
|
||||
int num_parts;
|
||||
uint32_t chip_size = g_rom_flashchip.chip_size;
|
||||
*num_partitions = 0;
|
||||
|
||||
for(num_parts = 0; num_parts < ESP_PARTITION_TABLE_MAX_ENTRIES; num_parts++) {
|
||||
const esp_partition_info_t *part = &partition_table[num_parts];
|
||||
|
||||
if (part->magic == 0xFFFF
|
||||
&& part->type == PART_TYPE_END
|
||||
&& part->subtype == PART_SUBTYPE_END) {
|
||||
/* TODO: check md5 */
|
||||
ESP_LOGD(TAG, "partition table verified, %d entries", num_parts);
|
||||
*num_partitions = num_parts;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
if (part->magic != ESP_PARTITION_MAGIC) {
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "partition %d invalid magic number 0x%x", num_parts, part->magic);
|
||||
}
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
const esp_partition_pos_t *pos = &part->pos;
|
||||
if (pos->offset > chip_size || pos->offset + pos->size > chip_size) {
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "partition %d invalid - offset 0x%x size 0x%x exceeds flash chip size 0x%x",
|
||||
num_parts, pos->offset, pos->size, chip_size);
|
||||
}
|
||||
return ESP_ERR_INVALID_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
if (log_errors) {
|
||||
ESP_LOGE(TAG, "partition table has no terminating entry, not valid");
|
||||
}
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
204
components/bootloader_support/src/secure_boot.c
Normal file
204
components/bootloader_support/src/secure_boot.c
Normal file
@@ -0,0 +1,204 @@
|
||||
// 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 <string.h>
|
||||
|
||||
#include "esp_attr.h"
|
||||
#include "esp_types.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "rom/cache.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "rom/secure_boot.h"
|
||||
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_random.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_efuse.h"
|
||||
|
||||
static const char* TAG = "secure_boot";
|
||||
|
||||
/**
|
||||
* @function : secure_boot_generate
|
||||
* @description: generate boot digest (aka "abstract") & iv
|
||||
*
|
||||
* @inputs: image_len - length of image to calculate digest for
|
||||
*/
|
||||
static bool secure_boot_generate(uint32_t image_len){
|
||||
esp_err_t err;
|
||||
esp_secure_boot_iv_digest_t digest;
|
||||
const uint32_t *image;
|
||||
|
||||
/* hardware secure boot engine only takes full blocks, so round up the
|
||||
image length. The additional data should all be 0xFF.
|
||||
*/
|
||||
if (image_len % sizeof(digest.iv) != 0) {
|
||||
image_len = (image_len / sizeof(digest.iv) + 1) * sizeof(digest.iv);
|
||||
}
|
||||
ets_secure_boot_start();
|
||||
ets_secure_boot_rd_iv((uint32_t *)digest.iv);
|
||||
ets_secure_boot_hash(NULL);
|
||||
/* iv stored in sec 0 */
|
||||
err = bootloader_flash_erase_sector(0);
|
||||
if (err != ESP_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "SPI erase failed: 0x%x", err);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* generate digest from image contents */
|
||||
image = bootloader_mmap(0x1000, image_len);
|
||||
if (!image) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x1000, 0x%x) failed", image_len);
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < image_len; i+= sizeof(digest.iv)) {
|
||||
ets_secure_boot_hash(&image[i/sizeof(uint32_t)]);
|
||||
}
|
||||
bootloader_munmap(image);
|
||||
|
||||
ets_secure_boot_obtain();
|
||||
ets_secure_boot_rd_abstract((uint32_t *)digest.digest);
|
||||
ets_secure_boot_finish();
|
||||
|
||||
ESP_LOGD(TAG, "write iv+digest to flash");
|
||||
err = bootloader_flash_write(FLASH_OFFS_SECURE_BOOT_IV_DIGEST, &digest,
|
||||
sizeof(digest), esp_flash_encryption_enabled());
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "SPI write failed: 0x%x", err);
|
||||
return false;
|
||||
}
|
||||
Cache_Read_Enable(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* 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 err;
|
||||
uint32_t image_len = 0;
|
||||
if (esp_secure_boot_enabled())
|
||||
{
|
||||
ESP_LOGI(TAG, "bootloader secure boot is already enabled, continuing..");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
err = esp_image_basic_verify(0x1000, true, &image_len);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "bootloader image appears invalid! error %d", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
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
|
||||
&& REG_READ(EFUSE_BLK2_RDATA0_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK2_RDATA1_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK2_RDATA2_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK2_RDATA3_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK2_RDATA4_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK2_RDATA5_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK2_RDATA6_REG) == 0
|
||||
&& REG_READ(EFUSE_BLK2_RDATA7_REG) == 0) {
|
||||
ESP_LOGI(TAG, "Generating new secure boot key...");
|
||||
uint32_t buf[8];
|
||||
bootloader_fill_random(buf, sizeof(buf));
|
||||
for (int i = 0; i < 8; i++) {
|
||||
ESP_LOGV(TAG, "EFUSE_BLK2_WDATA%d_REG = 0x%08x", i, buf[i]);
|
||||
REG_WRITE(EFUSE_BLK2_WDATA0_REG + 4*i, buf[i]);
|
||||
}
|
||||
bzero(buf, sizeof(buf));
|
||||
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");
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Generating secure boot digest...");
|
||||
if (false == secure_boot_generate(image_len)){
|
||||
ESP_LOGE(TAG, "secure boot generation failed");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
ESP_LOGI(TAG, "Digest generation complete.");
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_TEST_MODE
|
||||
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;
|
||||
}
|
||||
if (!efuse_key_write_protected) {
|
||||
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));
|
||||
|
||||
uint32_t new_wdata6 = EFUSE_RD_ABS_DONE_0;
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_ALLOW_JTAG
|
||||
ESP_LOGI(TAG, "Disable JTAG...");
|
||||
new_wdata6 |= EFUSE_RD_DISABLE_JTAG;
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling JTAG - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC
|
||||
ESP_LOGI(TAG, "Disable ROM BASIC interpreter fallback...");
|
||||
new_wdata6 |= EFUSE_RD_CONSOLE_DEBUG_DISABLE;
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling ROM BASIC fallback - SECURITY COMPROMISED");
|
||||
#endif
|
||||
|
||||
REG_WRITE(EFUSE_BLK0_WDATA6_REG, new_wdata6);
|
||||
burn_efuses();
|
||||
uint32_t after = REG_READ(EFUSE_BLK0_RDATA6_REG);
|
||||
ESP_LOGD(TAG, "after updating, EFUSE_BLK0_RDATA6 %x", after);
|
||||
if (after & EFUSE_RD_ABS_DONE_0) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
102
components/bootloader_support/src/secure_boot_signatures.c
Normal file
102
components/bootloader_support/src/secure_boot_signatures.c
Normal file
@@ -0,0 +1,102 @@
|
||||
// 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 "sdkconfig.h"
|
||||
|
||||
#include "bootloader_flash.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_secure_boot.h"
|
||||
|
||||
#include "uECC.h"
|
||||
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
#include "rom/sha.h"
|
||||
typedef SHA_CTX sha_context;
|
||||
#else
|
||||
#include "hwcrypto/sha.h"
|
||||
#endif
|
||||
|
||||
static const char* TAG = "secure_boot";
|
||||
|
||||
extern const uint8_t signature_verification_key_start[] asm("_binary_signature_verification_key_bin_start");
|
||||
extern const uint8_t signature_verification_key_end[] asm("_binary_signature_verification_key_bin_end");
|
||||
|
||||
#define SIGNATURE_VERIFICATION_KEYLEN 64
|
||||
|
||||
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
|
||||
{
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
SHA_CTX sha;
|
||||
#endif
|
||||
uint8_t digest[32];
|
||||
ptrdiff_t keylen;
|
||||
const uint8_t *data;
|
||||
const esp_secure_boot_sig_block_t *sigblock;
|
||||
bool is_valid;
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
const uint8_t *digest_data;
|
||||
uint32_t digest_len;
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
sigblock = (const esp_secure_boot_sig_block_t *)(data + length);
|
||||
|
||||
if (sigblock->version != 0) {
|
||||
ESP_LOGE(TAG, "src 0x%x has invalid signature version field 0x%08x", src_addr, sigblock->version);
|
||||
goto unmap_and_fail;
|
||||
}
|
||||
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
/* Use ROM SHA functions directly */
|
||||
ets_sha_enable();
|
||||
ets_sha_init(&sha);
|
||||
digest_len = length * 8;
|
||||
digest_data = data;
|
||||
while (digest_len > 0) {
|
||||
uint32_t chunk_len = (digest_len > 64) ? 64 : digest_len;
|
||||
ets_sha_update(&sha, SHA2_256, digest_data, chunk_len);
|
||||
digest_len -= chunk_len;
|
||||
digest_data += chunk_len / 8;
|
||||
}
|
||||
ets_sha_finish(&sha, SHA2_256, digest);
|
||||
ets_sha_disable();
|
||||
#else
|
||||
/* Use thread-safe esp-idf SHA function */
|
||||
esp_sha(SHA2_256, data, length, digest);
|
||||
#endif
|
||||
|
||||
keylen = signature_verification_key_end - signature_verification_key_start;
|
||||
if(keylen != SIGNATURE_VERIFICATION_KEYLEN) {
|
||||
ESP_LOGE(TAG, "Embedded public verification key has wrong length %d", keylen);
|
||||
goto unmap_and_fail;
|
||||
}
|
||||
|
||||
is_valid = uECC_verify(signature_verification_key_start,
|
||||
digest, sizeof(digest), sigblock->signature,
|
||||
uECC_secp256r1());
|
||||
|
||||
bootloader_munmap(data);
|
||||
return is_valid ? ESP_OK : ESP_ERR_IMAGE_INVALID;
|
||||
|
||||
unmap_and_fail:
|
||||
bootloader_munmap(data);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
@@ -1,29 +1,33 @@
|
||||
menu "BT config"
|
||||
visible if MEMMAP_BT
|
||||
|
||||
|
||||
config BT_ENABLED
|
||||
bool
|
||||
depends on ESP32_ENABLE_STACK_BT
|
||||
menuconfig BT_ENABLED
|
||||
bool "Bluetooth"
|
||||
help
|
||||
This compiles in the low-level BT stack.
|
||||
Select this option to enable Bluetooth stack and show the submenu with Bluetooth configuration choices.
|
||||
|
||||
#config BT_BTLE
|
||||
# bool "Enable BTLE"
|
||||
# depends on BT_ENABLED
|
||||
# help
|
||||
# This compiles BTLE support
|
||||
#
|
||||
#config BT_BT
|
||||
# bool "Enable classic BT"
|
||||
# depends on BT_ENABLED
|
||||
# help
|
||||
# This enables classic BT support
|
||||
config BTC_TASK_STACK_SIZE
|
||||
int "Bluetooth event (callback to application) task stack size"
|
||||
depends on BT_ENABLED
|
||||
default 3072
|
||||
help
|
||||
This select btc task stack size
|
||||
|
||||
endmenu
|
||||
config BLUEDROID_MEM_DEBUG
|
||||
bool "Bluedroid memory debug"
|
||||
depends on BT_ENABLED
|
||||
default n
|
||||
help
|
||||
Bluedroid memory debug
|
||||
|
||||
config BT_DRAM_RELEASE
|
||||
bool "Release DRAM from Classic BT controller"
|
||||
depends on BT_ENABLED
|
||||
default n
|
||||
help
|
||||
This option should only be used when BLE only.
|
||||
Open this option will release about 30K DRAM from Classic BT.
|
||||
The released DRAM will be used as system heap memory.
|
||||
|
||||
# Memory reserved at start of DRAM for Bluetooth stack
|
||||
config BT_RESERVE_DRAM
|
||||
hex
|
||||
default 0x10000 if MEMMAP_BT
|
||||
default 0x10000 if BT_ENABLED
|
||||
default 0
|
||||
|
||||
94
components/bt/bluedroid/api/esp_blufi_api.c
Normal file
94
components/bt/bluedroid/api/esp_blufi_api.c
Normal file
@@ -0,0 +1,94 @@
|
||||
// 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 "esp_blufi_api.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "btc_task.h"
|
||||
#include "btc_blufi_prf.h"
|
||||
#include "btc_manage.h"
|
||||
#include "btc_main.h"
|
||||
#include "future.h"
|
||||
|
||||
esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks)
|
||||
{
|
||||
if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (callbacks == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_blufi_set_callbacks(callbacks);
|
||||
return (btc_profile_cb_set(BTC_PID_BLUFI, callbacks->event_cb) == 0 ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_blufi_send_wifi_conn_report(wifi_mode_t opmode, esp_blufi_sta_conn_state_t sta_conn_state, uint8_t softap_conn_num, esp_blufi_extra_info_t *extra_info)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_blufi_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = BTC_BLUFI_ACT_SEND_CFG_REPORT;
|
||||
arg.wifi_conn_report.opmode = opmode;
|
||||
arg.wifi_conn_report.sta_conn_state = sta_conn_state;
|
||||
arg.wifi_conn_report.softap_conn_num = softap_conn_num;
|
||||
arg.wifi_conn_report.extra_info = extra_info;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), btc_blufi_call_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_blufi_profile_init(void)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = BTC_BLUFI_ACT_INIT;
|
||||
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_blufi_profile_deinit(void)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = BTC_BLUFI_ACT_DEINIT;
|
||||
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
uint16_t esp_blufi_get_version(void)
|
||||
{
|
||||
return btc_blufi_get_version();
|
||||
}
|
||||
|
||||
26
components/bt/bluedroid/api/esp_bt_device.c
Normal file
26
components/bt/bluedroid/api/esp_bt_device.c
Normal file
@@ -0,0 +1,26 @@
|
||||
// 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 "esp_bt_device.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "controller.h"
|
||||
|
||||
const uint8_t *esp_bt_dev_get_address(void)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return NULL;
|
||||
}
|
||||
return controller_get_interface()->get_address()->address;
|
||||
}
|
||||
185
components/bt/bluedroid/api/esp_bt_main.c
Normal file
185
components/bt/bluedroid/api/esp_bt_main.c
Normal file
@@ -0,0 +1,185 @@
|
||||
// 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 "esp_bt_main.h"
|
||||
#include "btc_task.h"
|
||||
#include "btc_main.h"
|
||||
#include "bt.h"
|
||||
#include "future.h"
|
||||
|
||||
static bool bd_already_enable = false;
|
||||
static bool bd_already_init = false;
|
||||
|
||||
esp_bluedroid_status_t esp_bluedroid_get_status(void)
|
||||
{
|
||||
if (bd_already_init) {
|
||||
if (bd_already_enable) {
|
||||
return ESP_BLUEDROID_STATUS_ENABLED;
|
||||
} else {
|
||||
return ESP_BLUEDROID_STATUS_INITIALIZED;
|
||||
}
|
||||
} else {
|
||||
return ESP_BLUEDROID_STATUS_UNINITIALIZED;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t esp_bluedroid_enable(void)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
future_t **future_p;
|
||||
|
||||
if (!bd_already_init) {
|
||||
LOG_ERROR("Bludroid not initialised\n");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (bd_already_enable) {
|
||||
LOG_ERROR("Bluedroid already enabled\n");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
future_p = btc_main_get_future_p(BTC_MAIN_ENABLE_FUTURE);
|
||||
*future_p = future_new();
|
||||
if (*future_p == NULL) {
|
||||
LOG_ERROR("Bluedroid enable failed\n");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_MAIN_INIT;
|
||||
msg.act = BTC_MAIN_ACT_ENABLE;
|
||||
btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
|
||||
if (future_await(*future_p) == FUTURE_FAIL) {
|
||||
LOG_ERROR("Bluedroid enable failed\n");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
bd_already_enable = true;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_bluedroid_disable(void)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
future_t **future_p;
|
||||
|
||||
if (!bd_already_enable) {
|
||||
LOG_ERROR("Bluedroid already disabled\n");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
future_p = btc_main_get_future_p(BTC_MAIN_DISABLE_FUTURE);
|
||||
*future_p = future_new();
|
||||
if (*future_p == NULL) {
|
||||
LOG_ERROR("Bluedroid disable failed\n");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_MAIN_INIT;
|
||||
msg.act = BTC_MAIN_ACT_DISABLE;
|
||||
btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
|
||||
if (future_await(*future_p) == FUTURE_FAIL) {
|
||||
LOG_ERROR("Bluedroid disable failed\n");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
bd_already_enable = false;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_bluedroid_init(void)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
future_t **future_p;
|
||||
|
||||
if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
|
||||
LOG_ERROR("Conroller not initialised\n");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (bd_already_init) {
|
||||
LOG_ERROR("Bluedroid already initialised\n");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
future_p = btc_main_get_future_p(BTC_MAIN_INIT_FUTURE);
|
||||
*future_p = future_new();
|
||||
if (*future_p == NULL) {
|
||||
LOG_ERROR("Bluedroid initialise failed\n");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
btc_init();
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_MAIN_INIT;
|
||||
msg.act = BTC_MAIN_ACT_INIT;
|
||||
btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
|
||||
if (future_await(*future_p) == FUTURE_FAIL) {
|
||||
LOG_ERROR("Bluedroid initialise failed\n");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
bd_already_init = true;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_bluedroid_deinit(void)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
future_t **future_p;
|
||||
|
||||
if (!bd_already_init) {
|
||||
LOG_ERROR("Bluedroid already de-initialised\n");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (bd_already_enable) {
|
||||
LOG_ERROR("Bludroid already enabled, do disable first\n");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
future_p = btc_main_get_future_p(BTC_MAIN_DEINIT_FUTURE);
|
||||
*future_p = future_new();
|
||||
if (*future_p == NULL) {
|
||||
LOG_ERROR("Bluedroid de-initialise failed\n");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_MAIN_INIT;
|
||||
msg.act = BTC_MAIN_ACT_DEINIT;
|
||||
btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
|
||||
if (future_await(*future_p) == FUTURE_FAIL) {
|
||||
LOG_ERROR("Bluedroid de-initialise failed\n");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_deinit();
|
||||
|
||||
bd_already_init = false;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
301
components/bt/bluedroid/api/esp_gap_ble_api.c
Normal file
301
components/bt/bluedroid/api/esp_gap_ble_api.c
Normal file
@@ -0,0 +1,301 @@
|
||||
// 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 <string.h>
|
||||
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_gap_ble_api.h"
|
||||
#include "bta_api.h"
|
||||
#include "bt_trace.h"
|
||||
#include "btc_manage.h"
|
||||
#include "btc_gap_ble.h"
|
||||
|
||||
|
||||
esp_err_t esp_ble_gap_register_callback(esp_gap_ble_cb_t callback)
|
||||
{
|
||||
if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
return (btc_profile_cb_set(BTC_PID_GAP_BLE, callback) == 0 ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_ble_gap_config_adv_data(esp_ble_adv_data_t *adv_data)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (adv_data == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (adv_data->service_uuid_len & 0xf) { //not 16*n
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_CFG_ADV_DATA;
|
||||
memcpy(&arg.cfg_adv_data.adv_data, adv_data, sizeof(esp_ble_adv_data_t));
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_ble_gap_set_scan_params(esp_ble_scan_params_t *scan_params)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (scan_params == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_SET_SCAN_PARAM;
|
||||
memcpy(&arg.set_scan_param.scan_params, scan_params, sizeof(esp_ble_scan_params_t));
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gap_start_scanning(uint32_t duration)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_START_SCAN;
|
||||
arg.start_scan.duration = duration;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_ble_gap_stop_scanning(void)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_STOP_SCAN;
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gap_start_advertising(esp_ble_adv_params_t *adv_params)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_START_ADV;
|
||||
memcpy(&arg.start_adv.adv_params, adv_params, sizeof(esp_ble_adv_params_t));
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gap_stop_advertising(void)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_STOP_ADV;
|
||||
|
||||
return (btc_transfer_context(&msg, NULL, 0, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_ble_gap_update_conn_params(esp_ble_conn_update_params_t *params)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_UPDATE_CONN_PARAM;
|
||||
memcpy(&arg.conn_update_params.conn_params, params, sizeof(esp_ble_conn_update_params_t));
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gap_set_pkt_data_len(esp_bd_addr_t remote_device, uint16_t tx_data_length)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_SET_PKT_DATA_LEN;
|
||||
arg.set_pkt_data_len.tx_data_length = tx_data_length;
|
||||
memcpy(arg.set_pkt_data_len.remote_device, remote_device, ESP_BD_ADDR_LEN);
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_ble_gap_set_rand_addr(esp_bd_addr_t rand_addr)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_SET_RAND_ADDRESS;
|
||||
memcpy(arg.set_rand_addr.rand_addr, rand_addr, ESP_BD_ADDR_LEN);
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_ble_gap_config_local_privacy (bool privacy_enable)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_CONFIG_LOCAL_PRIVACY;
|
||||
arg.cfg_local_privacy.privacy_enable = privacy_enable;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gap_set_device_name(const char *name)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (strlen(name) > ESP_GAP_DEVICE_NAME_MAX) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_SET_DEV_NAME;
|
||||
strcpy(arg.set_dev_name.device_name, name);
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
uint8_t *esp_ble_resolve_adv_data( uint8_t *adv_data, uint8_t type, uint8_t *length)
|
||||
{
|
||||
if (((type < ESP_BLE_AD_TYPE_FLAG) || (type > ESP_BLE_AD_TYPE_128SERVICE_DATA)) &&
|
||||
(type != ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE)) {
|
||||
LOG_ERROR("the eir type not define, type = %x\n", type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (adv_data == NULL) {
|
||||
LOG_ERROR("Invalid p_eir data.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (BTM_CheckAdvData( adv_data, type, length));
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gap_config_adv_data_raw(uint8_t *raw_data, uint32_t raw_data_len)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (raw_data == NULL
|
||||
|| (raw_data_len <= 0 || raw_data_len > ESP_BLE_ADV_DATA_LEN_MAX)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_CFG_ADV_DATA_RAW;
|
||||
arg.cfg_adv_data_raw.raw_adv = raw_data;
|
||||
arg.cfg_adv_data_raw.raw_adv_len = raw_data_len;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_data_len)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (raw_data == NULL
|
||||
|| (raw_data_len <= 0 || raw_data_len > ESP_BLE_SCAN_RSP_DATA_LEN_MAX)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_CFG_SCAN_RSP_DATA_RAW;
|
||||
arg.cfg_scan_rsp_data_raw.raw_scan_rsp = raw_data;
|
||||
arg.cfg_scan_rsp_data_raw.raw_scan_rsp_len = raw_data_len;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
|
||||
}
|
||||
452
components/bt/bluedroid/api/esp_gattc_api.c
Normal file
452
components/bt/bluedroid/api/esp_gattc_api.c
Normal file
@@ -0,0 +1,452 @@
|
||||
// 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 <string.h>
|
||||
|
||||
#include "esp_gattc_api.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "btc_manage.h"
|
||||
#include "btc_gattc.h"
|
||||
#include "btc_gatt_util.h"
|
||||
|
||||
esp_err_t esp_ble_gattc_register_callback(esp_gattc_cb_t callback)
|
||||
{
|
||||
if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (callback == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_profile_cb_set(BTC_PID_GATTC, callback);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_app_register(uint16_t app_id)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (app_id > ESP_APP_ID_MAX) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_APP_REGISTER;
|
||||
arg.app_reg.app_id = app_id;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_app_unregister(esp_gatt_if_t gattc_if)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_APP_UNREGISTER;
|
||||
arg.app_unreg.gattc_if = gattc_if;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_open(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, bool is_direct)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_OPEN;
|
||||
arg.open.gattc_if = gattc_if;
|
||||
memcpy(arg.open.remote_bda, remote_bda, ESP_BD_ADDR_LEN);
|
||||
arg.open.is_direct = is_direct;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_close (esp_gatt_if_t gattc_if, uint16_t conn_id)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_CLOSE;
|
||||
arg.close.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_config_mtu (esp_gatt_if_t gattc_if, uint16_t conn_id, uint16_t mtu)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if ((mtu < ESP_GATT_DEF_BLE_MTU_SIZE) || (mtu > ESP_GATT_MAX_MTU_SIZE)) {
|
||||
return ESP_GATT_ILLEGAL_PARAMETER;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_CFG_MTU;
|
||||
arg.cfg_mtu.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
|
||||
arg.cfg_mtu.mtu = mtu;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_search_service(esp_gatt_if_t gattc_if, uint16_t conn_id, esp_bt_uuid_t *filter_uuid)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_SEARCH_SERVICE;
|
||||
arg.search_srvc.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
|
||||
|
||||
if (filter_uuid) {
|
||||
arg.search_srvc.filter_uuid_enable = true;
|
||||
memcpy(&arg.search_srvc.filter_uuid, filter_uuid, sizeof(esp_bt_uuid_t));
|
||||
} else {
|
||||
arg.search_srvc.filter_uuid_enable = false;
|
||||
}
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_get_characteristic(esp_gatt_if_t gattc_if,
|
||||
uint16_t conn_id,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *start_char_id)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
if (start_char_id) {
|
||||
arg.get_next_char.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
|
||||
memcpy(&arg.get_next_char.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
|
||||
memcpy(&arg.get_next_char.char_id, start_char_id, sizeof(esp_gatt_id_t));
|
||||
msg.act = BTC_GATTC_ACT_GET_NEXT_CHAR;
|
||||
} else {
|
||||
arg.get_first_char.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
|
||||
memcpy(&arg.get_first_char.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
|
||||
msg.act = BTC_GATTC_ACT_GET_FIRST_CHAR;
|
||||
}
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_get_descriptor(esp_gatt_if_t gattc_if,
|
||||
uint16_t conn_id,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id,
|
||||
esp_gatt_id_t *start_descr_id)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
|
||||
if (start_descr_id) {
|
||||
arg.get_next_descr.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
|
||||
memcpy(&arg.get_next_descr.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
|
||||
memcpy(&arg.get_next_descr.char_id, char_id, sizeof(esp_gatt_id_t));
|
||||
memcpy(&arg.get_next_descr.descr_id, start_descr_id, sizeof(esp_gatt_id_t));
|
||||
msg.act = BTC_GATTC_ACT_GET_NEXT_DESCR;
|
||||
} else {
|
||||
arg.get_first_descr.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
|
||||
memcpy(&arg.get_first_descr.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
|
||||
memcpy(&arg.get_first_descr.char_id, char_id, sizeof(esp_gatt_id_t));
|
||||
msg.act = BTC_GATTC_ACT_GET_FIRST_DESCR;
|
||||
}
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_get_included_service(esp_gatt_if_t gattc_if,
|
||||
uint16_t conn_id,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_srvc_id_t *start_incl_srvc_id)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
|
||||
if (start_incl_srvc_id) {
|
||||
arg.get_next_incl_srvc.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
|
||||
memcpy(&arg.get_next_incl_srvc.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
|
||||
memcpy(&arg.get_next_incl_srvc.start_service_id, start_incl_srvc_id, sizeof(esp_gatt_srvc_id_t));
|
||||
msg.act = BTC_GATTC_ACT_GET_NEXT_INCL_SERVICE;
|
||||
} else {
|
||||
arg.get_first_incl_srvc.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
|
||||
memcpy(&arg.get_first_incl_srvc.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
|
||||
msg.act = BTC_GATTC_ACT_GET_FIRST_INCL_SERVICE;
|
||||
}
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_read_char (esp_gatt_if_t gattc_if,
|
||||
uint16_t conn_id,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id,
|
||||
esp_gatt_auth_req_t auth_req)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_READ_CHAR;
|
||||
arg.read_char.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
|
||||
memcpy(&arg.read_char.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
|
||||
memcpy(&arg.read_char.char_id, char_id, sizeof(esp_gatt_id_t));
|
||||
arg.read_char.auth_req = auth_req;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_read_char_descr (esp_gatt_if_t gattc_if,
|
||||
uint16_t conn_id,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id,
|
||||
esp_gatt_id_t *descr_id,
|
||||
esp_gatt_auth_req_t auth_req)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_READ_CHAR_DESCR;
|
||||
arg.read_descr.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
|
||||
memcpy(&arg.read_descr.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
|
||||
memcpy(&arg.read_descr.char_id, char_id, sizeof(esp_gatt_id_t));
|
||||
memcpy(&arg.read_descr.descr_id, descr_id, sizeof(esp_gatt_id_t));
|
||||
arg.read_descr.auth_req = auth_req;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_write_char( esp_gatt_if_t gattc_if,
|
||||
uint16_t conn_id,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id,
|
||||
uint16_t value_len,
|
||||
uint8_t *value,
|
||||
esp_gatt_write_type_t write_type,
|
||||
esp_gatt_auth_req_t auth_req)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_WRITE_CHAR;
|
||||
arg.write_char.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
|
||||
memcpy(&arg.write_char.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
|
||||
memcpy(&arg.write_char.char_id, char_id, sizeof(esp_gatt_id_t));
|
||||
arg.write_char.value_len = value_len > ESP_GATT_MAX_ATTR_LEN ? ESP_GATT_MAX_ATTR_LEN : value_len;
|
||||
arg.write_char.value = value;
|
||||
arg.write_char.write_type = write_type;
|
||||
arg.write_char.auth_req = auth_req;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), btc_gattc_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if,
|
||||
uint16_t conn_id,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id,
|
||||
esp_gatt_id_t *descr_id,
|
||||
uint16_t value_len,
|
||||
uint8_t *value,
|
||||
esp_gatt_write_type_t write_type,
|
||||
esp_gatt_auth_req_t auth_req)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_WRITE_CHAR_DESCR;
|
||||
arg.write_descr.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
|
||||
memcpy(&arg.write_descr.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
|
||||
memcpy(&arg.write_descr.char_id, char_id, sizeof(esp_gatt_id_t));
|
||||
memcpy(&arg.write_descr.descr_id, descr_id, sizeof(esp_gatt_id_t));
|
||||
arg.write_descr.value_len = value_len > ESP_GATT_MAX_ATTR_LEN ? ESP_GATT_MAX_ATTR_LEN : value_len;
|
||||
arg.write_descr.value = value;
|
||||
arg.write_descr.write_type = write_type;
|
||||
arg.write_descr.auth_req = auth_req;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), btc_gattc_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_prepare_write(esp_gatt_if_t gattc_if,
|
||||
uint16_t conn_id,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id,
|
||||
uint16_t offset,
|
||||
uint16_t value_len,
|
||||
uint8_t *value,
|
||||
esp_gatt_auth_req_t auth_req)
|
||||
{
|
||||
//TODO: Review this function
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_PREPARE_WRITE;
|
||||
arg.prep_write.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
|
||||
memcpy(&arg.prep_write.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
|
||||
memcpy(&arg.prep_write.char_id, char_id, sizeof(esp_gatt_id_t));
|
||||
arg.prep_write.offset = offset;
|
||||
arg.prep_write.value_len = value_len > ESP_GATT_MAX_ATTR_LEN ? ESP_GATT_MAX_ATTR_LEN : value_len; // length check ?
|
||||
arg.prep_write.value = value;
|
||||
arg.prep_write.auth_req = auth_req;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), btc_gattc_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_execute_write (esp_gatt_if_t gattc_if, uint16_t conn_id, bool is_execute)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_EXECUTE_WRITE;
|
||||
arg.exec_write.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
|
||||
arg.exec_write.is_execute = is_execute;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_gatt_status_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gattc_if,
|
||||
esp_bd_addr_t server_bda,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_REG_FOR_NOTIFY;
|
||||
arg.reg_for_notify.gattc_if = gattc_if;
|
||||
memcpy(arg.reg_for_notify.remote_bda, server_bda, sizeof(esp_bd_addr_t));
|
||||
memcpy(&arg.reg_for_notify.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
|
||||
memcpy(&arg.reg_for_notify.char_id, char_id, sizeof(esp_gatt_id_t));
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_gatt_status_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gattc_if,
|
||||
esp_bd_addr_t server_bda,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_UNREG_FOR_NOTIFY;
|
||||
arg.unreg_for_notify.gattc_if = gattc_if;
|
||||
memcpy(arg.unreg_for_notify.remote_bda, server_bda, sizeof(esp_bd_addr_t));
|
||||
memcpy(&arg.unreg_for_notify.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
|
||||
memcpy(&arg.unreg_for_notify.char_id, char_id, sizeof(esp_gatt_id_t));
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
401
components/bt/bluedroid/api/esp_gatts_api.c
Normal file
401
components/bt/bluedroid/api/esp_gatts_api.c
Normal file
@@ -0,0 +1,401 @@
|
||||
// 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 "string.h"
|
||||
#include "esp_gatt_defs.h"
|
||||
#include "esp_gatts_api.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "btc_manage.h"
|
||||
#include "btc_gatts.h"
|
||||
#include "btc_gatt_util.h"
|
||||
|
||||
#define COPY_TO_GATTS_ARGS(_gatt_args, _arg, _arg_type) memcpy(_gatt_args, _arg, sizeof(_arg_type))
|
||||
|
||||
|
||||
esp_err_t esp_ble_gatts_register_callback(esp_gatts_cb_t callback)
|
||||
{
|
||||
if (esp_bluedroid_get_status() == ESP_BLUEDROID_STATUS_UNINITIALIZED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
return (btc_profile_cb_set(BTC_PID_GATTS, callback) == 0 ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gatts_app_register(uint16_t app_id)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
//if (app_id < ESP_APP_ID_MIN || app_id > ESP_APP_ID_MAX) {
|
||||
if (app_id > ESP_APP_ID_MAX) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_APP_REGISTER;
|
||||
arg.app_reg.app_id = app_id;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_ble_gatts_app_unregister(esp_gatt_if_t gatts_if)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_APP_UNREGISTER;
|
||||
arg.app_unreg.gatts_if = gatts_if;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gatts_create_service(esp_gatt_if_t gatts_if,
|
||||
esp_gatt_srvc_id_t *service_id, uint16_t num_handle)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_CREATE_SERVICE;
|
||||
arg.create_srvc.gatts_if = gatts_if;
|
||||
arg.create_srvc.num_handle = num_handle;
|
||||
memcpy(&arg.create_srvc.service_id, service_id, sizeof(esp_gatt_srvc_id_t));
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gatts_create_attr_tab(const esp_gatts_attr_db_t *gatts_attr_db,
|
||||
esp_gatt_if_t gatts_if,
|
||||
uint8_t max_nb_attr,
|
||||
uint8_t srvc_inst_id)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_CREATE_ATTR_TAB;
|
||||
arg.create_attr_tab.gatts_if = gatts_if;
|
||||
arg.create_attr_tab.max_nb_attr = max_nb_attr;
|
||||
arg.create_attr_tab.srvc_inst_id = srvc_inst_id;
|
||||
arg.create_attr_tab.gatts_attr_db = (esp_gatts_attr_db_t *)gatts_attr_db;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_ble_gatts_add_included_service(uint16_t service_handle, uint16_t included_service_handle)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_ADD_INCLUDE_SERVICE;
|
||||
arg.add_incl_srvc.service_handle = service_handle;
|
||||
arg.add_incl_srvc.included_service_handle = included_service_handle;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_ble_gatts_add_char(uint16_t service_handle, esp_bt_uuid_t *char_uuid,
|
||||
esp_gatt_perm_t perm, esp_gatt_char_prop_t property, esp_attr_value_t *char_val,
|
||||
esp_attr_control_t *control)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
/* parameter validation check */
|
||||
if ((control != NULL) && (control->auto_rsp == GATT_STACK_RSP)){
|
||||
if (char_val == NULL){
|
||||
LOG_ERROR("Error in %s, line=%d, for stack respond attribute, char_val should not be NULL here\n",\
|
||||
__func__, __LINE__);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
} else if (char_val->attr_max_len == 0){
|
||||
LOG_ERROR("Error in %s, line=%d, for stack respond attribute, attribute max length should not be 0\n",\
|
||||
__func__, __LINE__);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
if (char_val != NULL){
|
||||
if (char_val->attr_len > char_val->attr_max_len){
|
||||
LOG_ERROR("Error in %s, line=%d,attribute actual length (%d) should not be larger than max length (%d)\n",\
|
||||
__func__, __LINE__, char_val->attr_len, char_val->attr_max_len);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
memset(&arg, 0, sizeof(btc_ble_gatts_args_t));
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_ADD_CHAR;
|
||||
arg.add_char.service_handle = service_handle;
|
||||
arg.add_char.perm = perm;
|
||||
arg.add_char.property = property;
|
||||
if (char_val != NULL) {
|
||||
arg.add_char.char_val.attr_max_len = char_val->attr_max_len;
|
||||
arg.add_char.char_val.attr_len = char_val->attr_len;
|
||||
arg.add_char.char_val.attr_value = char_val->attr_value;
|
||||
}
|
||||
|
||||
if (control != NULL) {
|
||||
arg.add_char.attr_control.auto_rsp = control->auto_rsp;
|
||||
}
|
||||
memcpy(&arg.add_char.char_uuid, char_uuid, sizeof(esp_bt_uuid_t));
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_ble_gatts_add_char_descr (uint16_t service_handle,
|
||||
esp_bt_uuid_t *descr_uuid,
|
||||
esp_gatt_perm_t perm, esp_attr_value_t *char_descr_val,
|
||||
esp_attr_control_t *control)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
/* parameter validation check */
|
||||
if ((control != NULL) && (control->auto_rsp == GATT_STACK_RSP)){
|
||||
if (char_descr_val == NULL){
|
||||
LOG_ERROR("Error in %s, line=%d, for stack respond attribute, char_descr_val should not be NULL here\n",\
|
||||
__func__, __LINE__);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
else if (char_descr_val->attr_max_len == 0){
|
||||
LOG_ERROR("Error in %s, line=%d, for stack respond attribute, attribute max length should not be 0\n",\
|
||||
__func__, __LINE__);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
if (char_descr_val != NULL){
|
||||
if (char_descr_val->attr_len > char_descr_val->attr_max_len){
|
||||
LOG_ERROR("Error in %s, line=%d,attribute actual length (%d) should not be larger than max length (%d)\n",\
|
||||
__func__, __LINE__, char_descr_val->attr_len, char_descr_val->attr_max_len);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
memset(&arg, 0, sizeof(btc_ble_gatts_args_t));
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_ADD_CHAR_DESCR;
|
||||
arg.add_descr.service_handle = service_handle;
|
||||
arg.add_descr.perm = perm;
|
||||
|
||||
if (char_descr_val != NULL) {
|
||||
arg.add_descr.descr_val.attr_max_len = char_descr_val->attr_max_len;
|
||||
arg.add_descr.descr_val.attr_len = char_descr_val->attr_len;
|
||||
arg.add_descr.descr_val.attr_value = char_descr_val->attr_value;
|
||||
}
|
||||
|
||||
if (control != NULL) {
|
||||
arg.add_descr.attr_control.auto_rsp = control->auto_rsp;
|
||||
}
|
||||
memcpy(&arg.add_descr.descr_uuid, descr_uuid, sizeof(esp_bt_uuid_t));
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gatts_delete_service(uint16_t service_handle)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_DELETE_SERVICE;
|
||||
arg.delete_srvc.service_handle = service_handle;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gatts_start_service(uint16_t service_handle)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_START_SERVICE;
|
||||
arg.start_srvc.service_handle = service_handle;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gatts_stop_service(uint16_t service_handle)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_STOP_SERVICE;
|
||||
arg.stop_srvc.service_handle = service_handle;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_ble_gatts_send_indicate(esp_gatt_if_t gatts_if, uint16_t conn_id, uint16_t attr_handle,
|
||||
uint16_t value_len, uint8_t *value, bool need_confirm)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_SEND_INDICATE;
|
||||
arg.send_ind.conn_id = BTC_GATT_CREATE_CONN_ID(gatts_if, conn_id);
|
||||
arg.send_ind.attr_handle = attr_handle;
|
||||
arg.send_ind.need_confirm = need_confirm;
|
||||
arg.send_ind.value_len = value_len;
|
||||
arg.send_ind.value = value;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t),
|
||||
btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gatts_send_response(esp_gatt_if_t gatts_if, uint16_t conn_id, uint32_t trans_id,
|
||||
esp_gatt_status_t status, esp_gatt_rsp_t *rsp)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_SEND_RESPONSE;
|
||||
arg.send_rsp.conn_id = BTC_GATT_CREATE_CONN_ID(gatts_if, conn_id);
|
||||
arg.send_rsp.trans_id = trans_id;
|
||||
arg.send_rsp.status = status;
|
||||
arg.send_rsp.rsp = rsp;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t),
|
||||
btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gatts_set_attr_value(uint16_t attr_handle, uint16_t length, const uint8_t *value)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_SET_ATTR_VALUE;
|
||||
arg.set_attr_val.length = length;
|
||||
arg.set_attr_val.value = (uint8_t *)value;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t),
|
||||
btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, const uint8_t **value)
|
||||
{
|
||||
if (attr_handle == ESP_GATT_ILLEGAL_HANDLE) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
btc_gatts_get_attr_value(attr_handle, length, (uint8_t **)value);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gatts_open(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda, bool is_direct)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_OPEN;
|
||||
arg.open.gatts_if = gatts_if;
|
||||
arg.open.is_direct = is_direct;
|
||||
memcpy(&arg.open.remote_bda, remote_bda, sizeof(esp_bd_addr_t));
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gatts_close(esp_gatt_if_t gatts_if, uint16_t conn_id)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_CLOSE;
|
||||
arg.close.conn_id = BTC_GATT_CREATE_CONN_ID(gatts_if, conn_id);
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
360
components/bt/bluedroid/api/include/esp_blufi_api.h
Normal file
360
components/bt/bluedroid/api/include/esp_blufi_api.h
Normal file
@@ -0,0 +1,360 @@
|
||||
// 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 __ESP_BLUFI_API_H__
|
||||
#define __ESP_BLUFI_API_H__
|
||||
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_gatt_defs.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_wifi_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
ESP_BLUFI_EVENT_INIT_FINISH = 0, /*<! When BLUFI init complete, this event happen */
|
||||
ESP_BLUFI_EVENT_DEINIT_FINISH, /*<! When BLUFI deinit complete, this event happen */
|
||||
ESP_BLUFI_EVENT_SET_WIFI_OPMODE, /*<! When Phone set ESP32 wifi operation mode(AP/STA/AP_STA), this event happen */
|
||||
ESP_BLUFI_EVENT_BLE_CONNECT, /*<! When Phone connect to ESP32 with BLE, this event happen */
|
||||
ESP_BLUFI_EVENT_BLE_DISCONNECT, /*<! When Phone disconnect with BLE, this event happen */
|
||||
ESP_BLUFI_EVENT_REQ_CONNECT_TO_AP, /*<! When Phone request ESP32's STA connect to AP, this event happen */
|
||||
ESP_BLUFI_EVENT_REQ_DISCONNECT_FROM_AP, /*<! When Phone request ESP32's STA disconnect from AP, this event happen */
|
||||
ESP_BLUFI_EVENT_GET_WIFI_STATUS, /*<! When Phone get ESP32 wifi status, this event happen */
|
||||
ESP_BLUFI_EVENT_DEAUTHENTICATE_STA, /*<! When Phone deauthenticate sta from SOFTAP, this event happen */
|
||||
/* recv data */
|
||||
ESP_BLUFI_EVENT_RECV_STA_BSSID, /*<! When Phone send STA BSSID to ESP32 to connect, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_STA_SSID, /*<! When Phone send STA SSID to ESP32 to connect, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_STA_PASSWD, /*<! When Phone send STA PASSWORD to ESP32 to connect, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_SOFTAP_SSID, /*<! When Phone send SOFTAP SSID to ESP32 to start SOFTAP, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD, /*<! When Phone send SOFTAP PASSWORD to ESP32 to start SOFTAP, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM, /*<! When Phone send SOFTAP max connection number to ESP32 to start SOFTAP, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE, /*<! When Phone send SOFTAP authentication mode to ESP32 to start SOFTAP, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL, /*<! When Phone send SOFTAP channel to ESP32 to start SOFTAP, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_USERNAME, /*<! When Phone send username to ESP32, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_CA_CERT, /*<! When Phone send CA certificate to ESP32, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_CLIENT_CERT, /*<! When Phone send Client certificate to ESP32, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_SERVER_CERT, /*<! When Phone send Server certificate to ESP32, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY, /*<! When Phone send Client Private key to ESP32, this event happen */
|
||||
ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY, /*<! When Phone send Server Private key to ESP32, this event happen */
|
||||
} esp_blufi_cb_event_t;
|
||||
|
||||
/// BLUFI config status
|
||||
typedef enum {
|
||||
ESP_BLUFI_STA_CONN_SUCCESS = 0x00,
|
||||
ESP_BLUFI_STA_CONN_FAIL = 0x01,
|
||||
} esp_blufi_sta_conn_state_t;
|
||||
|
||||
/// BLUFI init status
|
||||
typedef enum {
|
||||
ESP_BLUFI_INIT_OK = 0,
|
||||
ESP_BLUFI_INIT_FAILED = 0,
|
||||
} esp_blufi_init_state_t;
|
||||
|
||||
/// BLUFI deinit status
|
||||
typedef enum {
|
||||
ESP_BLUFI_DEINIT_OK = 0,
|
||||
ESP_BLUFI_DEINIT_FAILED = 0,
|
||||
} esp_blufi_deinit_state_t;
|
||||
|
||||
/**
|
||||
* @brief BLUFI extra information structure
|
||||
*/
|
||||
typedef struct {
|
||||
//station
|
||||
uint8_t sta_bssid[6]; /*!< BSSID of station interface */
|
||||
bool sta_bssid_set; /*!< is BSSID of station interface set */
|
||||
uint8_t *sta_ssid; /*!< SSID of station interface */
|
||||
int sta_ssid_len; /*!< length of SSID of station interface */
|
||||
uint8_t *sta_passwd; /*!< password of station interface */
|
||||
int sta_passwd_len; /*!< length of password of station interface */
|
||||
uint8_t *softap_ssid; /*!< SSID of softap interface */
|
||||
int softap_ssid_len; /*!< length of SSID of softap interface */
|
||||
uint8_t *softap_passwd; /*!< password of station interface */
|
||||
int softap_passwd_len; /*!< length of password of station interface */
|
||||
uint8_t softap_authmode; /*!< authentication mode of softap interface */
|
||||
bool softap_authmode_set; /*!< is authentication mode of softap interface set */
|
||||
uint8_t softap_max_conn_num; /*!< max connection number of softap interface */
|
||||
bool softap_max_conn_num_set; /*!< is max connection number of softap interface set */
|
||||
uint8_t softap_channel; /*!< channel of softap interface */
|
||||
bool softap_channel_set; /*!< is channel of softap interface set */
|
||||
} esp_blufi_extra_info_t;
|
||||
|
||||
/**
|
||||
* @brief BLUFI callback parameters union
|
||||
*/
|
||||
typedef union {
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_INIT_FINISH
|
||||
*/
|
||||
struct blufi_init_finish_evt_param {
|
||||
esp_blufi_init_state_t state; /*!< Initial status */
|
||||
} init_finish; /*!< Blufi callback param of ESP_BLUFI_EVENT_INIT_FINISH */
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_DEINIT_FINISH
|
||||
*/
|
||||
struct blufi_deinit_finish_evt_param {
|
||||
esp_blufi_deinit_state_t state; /*!< De-initial status */
|
||||
} deinit_finish; /*!< Blufi callback param of ESP_BLUFI_EVENT_DEINIT_FINISH */
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_SET_WIFI_MODE
|
||||
*/
|
||||
struct blufi_set_wifi_mode_evt_param {
|
||||
wifi_mode_t op_mode; /*!< Wifi operation mode */
|
||||
} wifi_mode; /*!< Blufi callback param of ESP_BLUFI_EVENT_INIT_FINISH */
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_CONNECT
|
||||
*/
|
||||
struct blufi_connect_evt_param {
|
||||
esp_bd_addr_t remote_bda; /*!< Blufi Remote bluetooth device address */
|
||||
} connect; /*!< Blufi callback param of ESP_BLUFI_EVENT_CONNECT */
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_DISCONNECT
|
||||
*/
|
||||
struct blufi_disconnect_evt_param {
|
||||
esp_bd_addr_t remote_bda; /*!< Blufi Remote bluetooth device address */
|
||||
} disconnect; /*!< Blufi callback param of ESP_BLUFI_EVENT_DISCONNECT */
|
||||
|
||||
/* ESP_BLUFI_EVENT_REQ_WIFI_CONNECT */ /* No callback param */
|
||||
/* ESP_BLUFI_EVENT_REQ_WIFI_DISCONNECT */ /* No callback param */
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_RECV_STA_BSSID
|
||||
*/
|
||||
struct blufi_recv_sta_bssid_evt_param {
|
||||
uint8_t bssid[6]; /*!< BSSID */
|
||||
} sta_bssid; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_STA_BSSID */
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_RECV_STA_SSID
|
||||
*/
|
||||
struct blufi_recv_sta_ssid_evt_param {
|
||||
uint8_t *ssid; /*!< SSID */
|
||||
int ssid_len; /*!< SSID length */
|
||||
} sta_ssid; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_STA_SSID */
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* ESP_BLUFI_EVENT_RECV_STA_PASSWD
|
||||
*/
|
||||
struct blufi_recv_sta_passwd_evt_param {
|
||||
uint8_t *passwd; /*!< Password */
|
||||
int passwd_len; /*!< Password Length */
|
||||
} sta_passwd; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_STA_PASSWD */
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_RECV_SOFTAP_SSID
|
||||
*/
|
||||
struct blufi_recv_softap_ssid_evt_param {
|
||||
uint8_t *ssid; /*!< SSID */
|
||||
int ssid_len; /*!< SSID length */
|
||||
} softap_ssid; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_SSID */
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD
|
||||
*/
|
||||
struct blufi_recv_softap_passwd_evt_param {
|
||||
uint8_t *passwd; /*!< Password */
|
||||
int passwd_len; /*!< Password Length */
|
||||
} softap_passwd; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_PASSWD */
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM
|
||||
*/
|
||||
struct blufi_recv_softap_max_conn_num_evt_param {
|
||||
int max_conn_num; /*!< SSID */
|
||||
} softap_max_conn_num; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_MAX_CONN_NUM */
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE
|
||||
*/
|
||||
struct blufi_recv_softap_auth_mode_evt_param {
|
||||
wifi_auth_mode_t auth_mode; /*!< Authentication mode */
|
||||
} softap_auth_mode; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_AUTH_MODE */
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL
|
||||
*/
|
||||
struct blufi_recv_softap_channel_evt_param {
|
||||
uint8_t channel; /*!< Authentication mode */
|
||||
} softap_channel; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SOFTAP_CHANNEL */
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_RECV_USERNAME
|
||||
*/
|
||||
struct blufi_recv_username_evt_param {
|
||||
uint8_t *name; /*!< Username point */
|
||||
int name_len; /*!< Username length */
|
||||
} username; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_USERNAME*/
|
||||
|
||||
/**
|
||||
* @brief ESP_BLUFI_EVENT_RECV_CA_CERT
|
||||
*/
|
||||
struct blufi_recv_ca_evt_param {
|
||||
uint8_t *cert; /*!< CA certificate point */
|
||||
int cert_len; /*!< CA certificate length */
|
||||
} ca; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_CA_CERT */
|
||||
|
||||
/**
|
||||
* ESP_BLUFI_EVENT_RECV_CLIENT_CERT
|
||||
*/
|
||||
struct blufi_recv_client_cert_evt_param {
|
||||
uint8_t *cert; /*!< Client certificate point */
|
||||
int cert_len; /*!< Client certificate length */
|
||||
} client_cert; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_CLIENT_CERT */
|
||||
|
||||
/**
|
||||
* ESP_BLUFI_EVENT_RECV_SERVER_CERT
|
||||
*/
|
||||
struct blufi_recv_server_cert_evt_param {
|
||||
uint8_t *cert; /*!< Client certificate point */
|
||||
int cert_len; /*!< Client certificate length */
|
||||
} server_cert; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SERVER_CERT */
|
||||
|
||||
/**
|
||||
* ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY
|
||||
*/
|
||||
struct blufi_recv_client_pkey_evt_param {
|
||||
uint8_t *pkey; /*!< Client Private Key point, if Client certificate not contain Key */
|
||||
int pkey_len; /*!< Client Private key length */
|
||||
} client_pkey; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_CLIENT_PRIV_KEY */
|
||||
/**
|
||||
* ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY
|
||||
*/
|
||||
struct blufi_recv_server_pkey_evt_param {
|
||||
uint8_t *pkey; /*!< Client Private Key point, if Client certificate not contain Key */
|
||||
int pkey_len; /*!< Client Private key length */
|
||||
} server_pkey; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_SERVER_PRIV_KEY */
|
||||
|
||||
} esp_blufi_cb_param_t;
|
||||
|
||||
/**
|
||||
* @brief BLUFI event callback function type
|
||||
* @param event : Event type
|
||||
* @param param : Point to callback parameter, currently is union type
|
||||
*/
|
||||
typedef void (* esp_blufi_event_cb_t)(esp_blufi_cb_event_t event, esp_blufi_cb_param_t *param);
|
||||
|
||||
/* security function declare */
|
||||
|
||||
/**
|
||||
* @brief BLUFI negotiate data handler
|
||||
* @param data : data from phone
|
||||
* @param len : length of data from phone
|
||||
* @param output_data : data want to send to phone
|
||||
* @param output_len : length of data want to send to phone
|
||||
*/
|
||||
typedef void (*esp_blufi_negotiate_data_handler_t)(uint8_t *data, int len, uint8_t **output_data, int *output_len, bool *need_free);
|
||||
|
||||
/**
|
||||
* @brief BLUFI encrypt the data after negotiate a share key
|
||||
* @param iv8 : initial vector(8bit), normally, blufi core will input packet sequence number
|
||||
* @param crypt_data : plain text and encrypted data, the encrypt function must support autochthonous encrypt
|
||||
* @param crypt_len : length of plain text
|
||||
* @return Nonnegative number is encrypted length, if error, return negative number;
|
||||
*/
|
||||
typedef int (* esp_blufi_encrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int cyprt_len);
|
||||
|
||||
/**
|
||||
* @brief BLUFI decrypt the data after negotiate a share key
|
||||
* @param iv8 : initial vector(8bit), normally, blufi core will input packet sequence number
|
||||
* @param crypt_data : encrypted data and plain text, the encrypt function must support autochthonous decrypt
|
||||
* @param crypt_len : length of encrypted text
|
||||
* @return Nonnegative number is decrypted length, if error, return negative number;
|
||||
*/
|
||||
typedef int (* esp_blufi_decrypt_func_t)(uint8_t iv8, uint8_t *crypt_data, int crypt_len);
|
||||
|
||||
/**
|
||||
* @brief BLUFI checksum
|
||||
* @param iv8 : initial vector(8bit), normally, blufi core will input packet sequence number
|
||||
* @param data : data need to checksum
|
||||
* @param len : length of data
|
||||
*/
|
||||
typedef uint16_t (*esp_blufi_checksum_func_t)(uint8_t iv8, uint8_t *data, int len);
|
||||
|
||||
/**
|
||||
* @brief BLUFI callback functions type
|
||||
*/
|
||||
typedef struct {
|
||||
esp_blufi_event_cb_t event_cb; /*!< BLUFI event callback */
|
||||
esp_blufi_negotiate_data_handler_t negotiate_data_handler; /*!< BLUFI negotiate data function for negotiate share key */
|
||||
esp_blufi_encrypt_func_t encrypt_func; /*!< BLUFI encrypt data function with share key generated by negotiate_data_handler */
|
||||
esp_blufi_decrypt_func_t decrypt_func; /*!< BLUFI decrypt data function with share key generated by negotiate_data_handler */
|
||||
esp_blufi_checksum_func_t checksum_func; /*!< BLUFI check sum function (FCS) */
|
||||
} esp_blufi_callbacks_t;
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief This function is called to receive blufi callback event
|
||||
*
|
||||
* @param[in] callbacks: callback functions
|
||||
*
|
||||
* @return ESP_OK - success, other - failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_blufi_register_callbacks(esp_blufi_callbacks_t *callbacks);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief This function is called to initialize blufi_profile
|
||||
*
|
||||
* @return ESP_OK - success, other - failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_blufi_profile_init(void);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief This function is called to de-initialize blufi_profile
|
||||
*
|
||||
* @return ESP_OK - success, other - failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_blufi_profile_deinit(void);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief This function is called to send wifi connection report
|
||||
* @param opmode : wifi opmode
|
||||
* @param sta_conn_state : station is already in connection or not
|
||||
* @param softap_conn_num : softap connection number
|
||||
* @param extra_info : extra information, such as sta_ssid, softap_ssid and etc.
|
||||
*
|
||||
* @return ESP_OK - success, other - failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_blufi_send_wifi_conn_report(wifi_mode_t opmode, esp_blufi_sta_conn_state_t sta_conn_state, uint8_t softap_conn_num, esp_blufi_extra_info_t *extra_info);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Get BLUFI profile version
|
||||
*
|
||||
* @return Most 8bit significant is Great version, Least 8bit is Sub version
|
||||
*
|
||||
*/
|
||||
uint16_t esp_blufi_get_version(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ESP_BLUFI_API_ */
|
||||
106
components/bt/bluedroid/api/include/esp_bt_defs.h
Normal file
106
components/bt/bluedroid/api/include/esp_bt_defs.h
Normal file
@@ -0,0 +1,106 @@
|
||||
// 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 __ESP_BT_DEFS_H__
|
||||
#define __ESP_BT_DEFS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Status Return Value
|
||||
typedef enum {
|
||||
ESP_BT_STATUS_SUCCESS = 0, /* Successful operation. */
|
||||
ESP_BT_STATUS_FAILURE = 1, /* Generic failure. */
|
||||
ESP_BT_STATUS_PENDING = 2, /* API cannot be completed right now */
|
||||
ESP_BT_STATUS_BUSY = 3,
|
||||
ESP_BT_STATUS_NO_RESOURCES = 4,
|
||||
ESP_BT_STATUS_WRONG_MODE = 5,
|
||||
} esp_bt_status_t;
|
||||
|
||||
/// Default GATT interface id
|
||||
#define ESP_DEFAULT_GATT_IF 0xff
|
||||
|
||||
/// Default BLE connection param, if the value doesn't be overwritten
|
||||
#define ESP_BLE_CONN_PARAM_UNDEF 0xffff /* use this value when a specific value not to be overwritten */
|
||||
|
||||
/// Check the param is valid or not
|
||||
#define ESP_BLE_IS_VALID_PARAM(x, min, max) (((x) >= (min) && (x) <= (max)) || ((x) == ESP_BLE_CONN_PARAM_UNDEF))
|
||||
|
||||
/// UUID type
|
||||
typedef struct {
|
||||
#define ESP_UUID_LEN_16 2
|
||||
#define ESP_UUID_LEN_32 4
|
||||
#define ESP_UUID_LEN_128 16
|
||||
uint16_t len; /*!< UUID length, 16bit, 32bit or 128bit */
|
||||
union {
|
||||
uint16_t uuid16;
|
||||
uint32_t uuid32;
|
||||
uint8_t uuid128[ESP_UUID_LEN_128];
|
||||
} uuid; /*!< UUID */
|
||||
} __attribute__((packed)) esp_bt_uuid_t;
|
||||
|
||||
/// Bluetooth device type
|
||||
typedef enum {
|
||||
ESP_BT_DEVICE_TYPE_BREDR = 0x01,
|
||||
ESP_BT_DEVICE_TYPE_BLE = 0x02,
|
||||
ESP_BT_DEVICE_TYPE_DUMO = 0x03,
|
||||
} esp_bt_dev_type_t;
|
||||
|
||||
/// Bluetooth address length
|
||||
#define ESP_BD_ADDR_LEN 6
|
||||
|
||||
/// Bluetooth device address
|
||||
typedef uint8_t esp_bd_addr_t[ESP_BD_ADDR_LEN];
|
||||
|
||||
/// Own BD address source of the device
|
||||
typedef enum {
|
||||
/// Public Address
|
||||
BD_ADDR_PUBLIC,
|
||||
/// Provided random address
|
||||
BD_ADDR_PROVIDED_RND,
|
||||
/// Provided static random address
|
||||
BD_ADDR_GEN_STATIC_RND,
|
||||
/// Generated resolvable private random address
|
||||
BD_ADDR_GEN_RSLV,
|
||||
/// Generated non-resolvable private random address
|
||||
BD_ADDR_GEN_NON_RSLV,
|
||||
/// Provided Reconnection address
|
||||
BD_ADDR_PROVIDED_RECON,
|
||||
} esp_bd_addr_type_t;
|
||||
|
||||
/// BLE device address type
|
||||
typedef enum {
|
||||
BLE_ADDR_TYPE_PUBLIC = 0x00,
|
||||
BLE_ADDR_TYPE_RANDOM = 0x01,
|
||||
BLE_ADDR_TYPE_RPA_PUBLIC = 0x02,
|
||||
BLE_ADDR_TYPE_RPA_RANDOM = 0x03,
|
||||
} esp_ble_addr_type_t;
|
||||
|
||||
/// Minimum of the application id
|
||||
#define ESP_APP_ID_MIN 0x0000
|
||||
/// Maximum of the application id
|
||||
#define ESP_APP_ID_MAX 0x7fff
|
||||
|
||||
#define ESP_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||
#define ESP_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_BT_DEFS_H__ */
|
||||
@@ -11,28 +11,28 @@
|
||||
// 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 __ESP_BT_DEVICE_H__
|
||||
#define __ESP_BT_DEVICE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
extern "C" unsigned long crc32_le(unsigned long crc_in, unsigned char const* data, unsigned int length)
|
||||
{
|
||||
uint32_t i;
|
||||
bool bit;
|
||||
uint8_t c;
|
||||
uint32_t crc = (uint32_t) crc_in;
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
while (length--) {
|
||||
c = *data++;
|
||||
for (i = 0x80; i > 0; i >>= 1) {
|
||||
bit = crc & 0x80000000;
|
||||
if (c & i) {
|
||||
bit = !bit;
|
||||
}
|
||||
crc <<= 1;
|
||||
if (bit) {
|
||||
crc ^= 0x04c11db7;
|
||||
}
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
/**
|
||||
*
|
||||
* @brief Get bluetooth device address. Must use after "esp_bluedroid_enable".
|
||||
*
|
||||
* @return bluetooth device address (six bytes), or NULL if bluetooth stack is not enabled
|
||||
*/
|
||||
const uint8_t *esp_bt_dev_get_address(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __ESP_BT_DEVICE_H__ */
|
||||
81
components/bt/bluedroid/api/include/esp_bt_main.h
Normal file
81
components/bt/bluedroid/api/include/esp_bt_main.h
Normal file
@@ -0,0 +1,81 @@
|
||||
// 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 __ESP_BT_MAIN_H__
|
||||
#define __ESP_BT_MAIN_H__
|
||||
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Bluetooth stack status type, to indicate whether the bluetooth stack is ready
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_BLUEDROID_STATUS_UNINITIALIZED = 0, /*!< Bluetooth not initialized */
|
||||
ESP_BLUEDROID_STATUS_INITIALIZED, /*!< Bluetooth initialized but not enabled */
|
||||
ESP_BLUEDROID_STATUS_ENABLED /*!< Bluetooth initialized and enabled */
|
||||
} esp_bluedroid_status_t;
|
||||
|
||||
/**
|
||||
* @brief Get bluetooth stack status
|
||||
*
|
||||
* @return Bluetooth stack status
|
||||
*
|
||||
*/
|
||||
esp_bluedroid_status_t esp_bluedroid_get_status(void);
|
||||
|
||||
/**
|
||||
* @brief Enable bluetooth, must after esp_bluedroid_init()
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Succeed
|
||||
* - Other : Failed
|
||||
*/
|
||||
esp_err_t esp_bluedroid_enable(void);
|
||||
|
||||
/**
|
||||
* @brief Disable bluetooth, must prior to esp_bluedroid_deinit()
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Succeed
|
||||
* - Other : Failed
|
||||
*/
|
||||
esp_err_t esp_bluedroid_disable(void);
|
||||
|
||||
/**
|
||||
* @brief Init and alloc the resource for bluetooth, must be prior to every bluetooth stuff
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Succeed
|
||||
* - Other : Failed
|
||||
*/
|
||||
esp_err_t esp_bluedroid_init(void);
|
||||
|
||||
/**
|
||||
* @brief Deinit and free the resource for bluetooth, must be after every bluetooth stuff
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Succeed
|
||||
* - Other : Failed
|
||||
*/
|
||||
esp_err_t esp_bluedroid_deinit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_BT_MAIN_H__ */
|
||||
510
components/bt/bluedroid/api/include/esp_gap_ble_api.h
Normal file
510
components/bt/bluedroid/api/include/esp_gap_ble_api.h
Normal file
@@ -0,0 +1,510 @@
|
||||
// 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 __ESP_GAP_BLE_API_H__
|
||||
#define __ESP_GAP_BLE_API_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_bt_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**@{
|
||||
* BLE_ADV_DATA_FLAG data flag bit definition used for advertising data flag
|
||||
*/
|
||||
#define ESP_BLE_ADV_FLAG_LIMIT_DISC (0x01 << 0)
|
||||
#define ESP_BLE_ADV_FLAG_GEN_DISC (0x01 << 1)
|
||||
#define ESP_BLE_ADV_FLAG_BREDR_NOT_SPT (0x01 << 2)
|
||||
#define ESP_BLE_ADV_FLAG_DMT_CONTROLLER_SPT (0x01 << 3)
|
||||
#define ESP_BLE_ADV_FLAG_DMT_HOST_SPT (0x01 << 4)
|
||||
#define ESP_BLE_ADV_FLAG_NON_LIMIT_DISC (0x00 )
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/// GAP BLE callback event type
|
||||
typedef enum {
|
||||
ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT = 0, /*!< When advertising data set complete, the event comes */
|
||||
ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT, /*!< When scan response data set complete, the event comes */
|
||||
ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT, /*!< When scan parameters set complete, the event comes */
|
||||
ESP_GAP_BLE_SCAN_RESULT_EVT, /*!< When one scan result ready, the event comes each time */
|
||||
ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT, /*!< When raw advertising data set complete, the event comes */
|
||||
ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT, /*!< When raw advertising data set complete, the event comes */
|
||||
ESP_GAP_BLE_ADV_START_COMPLETE_EVT, /*!< When start advertising complete, the event comes */
|
||||
ESP_GAP_BLE_SCAN_START_COMPLETE_EVT, /*!< When start scan complete, the event comes */
|
||||
} esp_gap_ble_cb_event_t;
|
||||
|
||||
/// Advertising data maximum length
|
||||
#define ESP_BLE_ADV_DATA_LEN_MAX 31
|
||||
/// Scan response data maximum length
|
||||
#define ESP_BLE_SCAN_RSP_DATA_LEN_MAX 31
|
||||
|
||||
/// The type of advertising data(not adv_type)
|
||||
typedef enum {
|
||||
ESP_BLE_AD_TYPE_FLAG = 0x01,
|
||||
ESP_BLE_AD_TYPE_16SRV_PART = 0x02,
|
||||
ESP_BLE_AD_TYPE_16SRV_CMPL = 0x03,
|
||||
ESP_BLE_AD_TYPE_32SRV_PART = 0x04,
|
||||
ESP_BLE_AD_TYPE_32SRV_CMPL = 0x05,
|
||||
ESP_BLE_AD_TYPE_128SRV_PART = 0x06,
|
||||
ESP_BLE_AD_TYPE_128SRV_CMPL = 0x07,
|
||||
ESP_BLE_AD_TYPE_NAME_SHORT = 0x08,
|
||||
ESP_BLE_AD_TYPE_NAME_CMPL = 0x09,
|
||||
ESP_BLE_AD_TYPE_TX_PWR = 0x0A,
|
||||
ESP_BLE_AD_TYPE_DEV_CLASS = 0x0D,
|
||||
ESP_BLE_AD_TYPE_SM_TK = 0x10,
|
||||
ESP_BLE_AD_TYPE_SM_OOB_FLAG = 0x11,
|
||||
ESP_BLE_AD_TYPE_INT_RANGE = 0x12,
|
||||
ESP_BLE_AD_TYPE_SOL_SRV_UUID = 0x14,
|
||||
ESP_BLE_AD_TYPE_128SOL_SRV_UUID = 0x15,
|
||||
ESP_BLE_AD_TYPE_SERVICE_DATA = 0x16,
|
||||
ESP_BLE_AD_TYPE_PUBLIC_TARGET = 0x17,
|
||||
ESP_BLE_AD_TYPE_RANDOM_TARGET = 0x18,
|
||||
ESP_BLE_AD_TYPE_APPEARANCE = 0x19,
|
||||
ESP_BLE_AD_TYPE_ADV_INT = 0x1A,
|
||||
ESP_BLE_AD_TYPE_32SOL_SRV_UUID = 0x1B,
|
||||
ESP_BLE_AD_TYPE_32SERVICE_DATA = 0x1C,
|
||||
ESP_BLE_AD_TYPE_128SERVICE_DATA = 0x1D,
|
||||
ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE = 0xFF,
|
||||
} esp_ble_adv_data_type;
|
||||
|
||||
/// Advertising mode
|
||||
typedef enum {
|
||||
ADV_TYPE_IND = 0x00,
|
||||
ADV_TYPE_DIRECT_IND_HIGH = 0x01,
|
||||
ADV_TYPE_SCAN_IND = 0x02,
|
||||
ADV_TYPE_NONCONN_IND = 0x03,
|
||||
ADV_TYPE_DIRECT_IND_LOW = 0x04,
|
||||
} esp_ble_adv_type_t;
|
||||
|
||||
/// Advertising channel mask
|
||||
typedef enum {
|
||||
ADV_CHNL_37 = 0x01,
|
||||
ADV_CHNL_38 = 0x02,
|
||||
ADV_CHNL_39 = 0x04,
|
||||
ADV_CHNL_ALL = 0x07,
|
||||
} esp_ble_adv_channel_t;
|
||||
|
||||
typedef enum {
|
||||
///Allow both scan and connection requests from anyone
|
||||
ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY = 0x00,
|
||||
///Allow both scan req from White List devices only and connection req from anyone
|
||||
ADV_FILTER_ALLOW_SCAN_WLST_CON_ANY,
|
||||
///Allow both scan req from anyone and connection req from White List devices only
|
||||
ADV_FILTER_ALLOW_SCAN_ANY_CON_WLST,
|
||||
///Allow scan and connection requests from White List devices only
|
||||
ADV_FILTER_ALLOW_SCAN_WLST_CON_WLST,
|
||||
///Enumeration end value for advertising filter policy value check
|
||||
} esp_ble_adv_filter_t;
|
||||
|
||||
/// Advertising parameters
|
||||
typedef struct {
|
||||
uint16_t adv_int_min; /*!< Minimum advertising interval for
|
||||
undirected and low duty cycle directed advertising.
|
||||
Range: 0x0020 to 0x4000 Default: N = 0x0800 (1.28 second)
|
||||
Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec */
|
||||
uint16_t adv_int_max; /*!< Maximum advertising interval for
|
||||
undirected and low duty cycle directed advertising.
|
||||
Range: 0x0020 to 0x4000 Default: N = 0x0800 (1.28 second)
|
||||
Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec Advertising max interval */
|
||||
esp_ble_adv_type_t adv_type; /*!< Advertising type */
|
||||
esp_ble_addr_type_t own_addr_type; /*!< Owner bluetooth device address type */
|
||||
esp_bd_addr_t peer_addr; /*!< Peer device bluetooth device address */
|
||||
esp_ble_addr_type_t peer_addr_type; /*!< Peer device bluetooth device address type */
|
||||
esp_ble_adv_channel_t channel_map; /*!< Advertising channel map */
|
||||
esp_ble_adv_filter_t adv_filter_policy; /*!< Advertising filter policy */
|
||||
} esp_ble_adv_params_t;
|
||||
|
||||
/// Advertising data content, according to "Supplement to the Bluetooth Core Specification"
|
||||
typedef struct {
|
||||
bool set_scan_rsp; /*!< Set this advertising data as scan response or not*/
|
||||
bool include_name; /*!< Advertising data include device name or not */
|
||||
bool include_txpower; /*!< Advertising data include TX power */
|
||||
int min_interval; /*!< Advertising data show advertising min interval */
|
||||
int max_interval; /*!< Advertising data show advertising max interval */
|
||||
int appearance; /*!< External appearance of device */
|
||||
uint16_t manufacturer_len; /*!< Manufacturer data length */
|
||||
uint8_t *p_manufacturer_data; /*!< Manufacturer data point */
|
||||
uint16_t service_data_len; /*!< Service data length */
|
||||
uint8_t *p_service_data; /*!< Service data point */
|
||||
uint16_t service_uuid_len; /*!< Service uuid length */
|
||||
uint8_t *p_service_uuid; /*!< Service uuid array point */
|
||||
uint8_t flag; /*!< Advertising flag of discovery mode, see BLE_ADV_DATA_FLAG detail */
|
||||
} esp_ble_adv_data_t;
|
||||
|
||||
/// Own BD address source of the device
|
||||
typedef enum {
|
||||
/// Public Address
|
||||
ESP_PUBLIC_ADDR,
|
||||
/// Provided random address
|
||||
ESP_PROVIDED_RND_ADDR,
|
||||
/// Provided static random address
|
||||
ESP_GEN_STATIC_RND_ADDR,
|
||||
/// Generated resolvable private random address
|
||||
ESP_GEN_RSLV_ADDR,
|
||||
/// Generated non-resolvable private random address
|
||||
ESP_GEN_NON_RSLV_ADDR,
|
||||
/// Provided Reconnection address
|
||||
ESP_PROVIDED_RECON_ADDR,
|
||||
} esp_ble_own_addr_src_t;
|
||||
|
||||
/// Ble scan type
|
||||
typedef enum {
|
||||
BLE_SCAN_TYPE_PASSIVE = 0x0, /*!< Passive scan */
|
||||
BLE_SCAN_TYPE_ACTIVE = 0x1, /*!< Active scan */
|
||||
} esp_ble_scan_type_t;
|
||||
|
||||
/// Ble scan filter type
|
||||
typedef enum {
|
||||
BLE_SCAN_FILTER_ALLOW_ALL = 0x0, /*!< Accept all :
|
||||
1. advertisement packets except directed advertising packets not addressed to this device (default). */
|
||||
BLE_SCAN_FILTER_ALLOW_ONLY_WLST = 0x1, /*!< Accept only :
|
||||
1. advertisement packets from devices where the advertiser’s address is in the White list.
|
||||
2. Directed advertising packets which are not addressed for this device shall be ignored. */
|
||||
BLE_SCAN_FILTER_ALLOW_UND_RPA_DIR = 0x2, /*!< Accept all :
|
||||
1. undirected advertisement packets, and
|
||||
2. directed advertising packets where the initiator address is a resolvable private address, and
|
||||
3. directed advertising packets addressed to this device. */
|
||||
BLE_SCAN_FILTER_ALLOW_WLIST_PRA_DIR = 0x3, /*!< Accept all :
|
||||
1. advertisement packets from devices where the advertiser’s address is in the White list, and
|
||||
2. directed advertising packets where the initiator address is a resolvable private address, and
|
||||
3. directed advertising packets addressed to this device.*/
|
||||
} esp_ble_scan_filter_t;
|
||||
|
||||
/// Ble scan parameters
|
||||
typedef struct {
|
||||
esp_ble_scan_type_t scan_type; /*!< Scan type */
|
||||
esp_ble_addr_type_t own_addr_type; /*!< Owner address type */
|
||||
esp_ble_scan_filter_t scan_filter_policy; /*!< Scan filter policy */
|
||||
uint16_t scan_interval; /*!< Scan interval. This is defined as the time interval from
|
||||
when the Controller started its last LE scan until it begins the subsequent LE scan.
|
||||
Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
|
||||
Time = N * 0.625 msec
|
||||
Time Range: 2.5 msec to 10.24 seconds*/
|
||||
uint16_t scan_window; /*!< Scan window. The duration of the LE scan. LE_Scan_Window
|
||||
shall be less than or equal to LE_Scan_Interval
|
||||
Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
|
||||
Time = N * 0.625 msec
|
||||
Time Range: 2.5 msec to 10240 msec */
|
||||
} esp_ble_scan_params_t;
|
||||
|
||||
/// Connection update parameters
|
||||
typedef struct {
|
||||
esp_bd_addr_t bda; /*!< Bluetooth device address */
|
||||
uint16_t min_int; /*!< Min connection interval */
|
||||
uint16_t max_int; /*!< Max connection interval */
|
||||
uint16_t latency; /*!< Slave latency for the connection in number of connection events. Range: 0x0000 to 0x01F3 */
|
||||
uint16_t timeout; /*!< Supervision timeout for the LE Link. Range: 0x000A to 0x0C80.
|
||||
Mandatory Range: 0x000A to 0x0C80 Time = N * 10 msec
|
||||
Time Range: 100 msec to 32 seconds */
|
||||
} esp_ble_conn_update_params_t;
|
||||
|
||||
/// Sub Event of ESP_GAP_BLE_SCAN_RESULT_EVT
|
||||
typedef enum {
|
||||
ESP_GAP_SEARCH_INQ_RES_EVT = 0, /*!< Inquiry result for a peer device. */
|
||||
ESP_GAP_SEARCH_INQ_CMPL_EVT = 1, /*!< Inquiry complete. */
|
||||
ESP_GAP_SEARCH_DISC_RES_EVT = 2, /*!< Discovery result for a peer device. */
|
||||
ESP_GAP_SEARCH_DISC_BLE_RES_EVT = 3, /*!< Discovery result for BLE GATT based service on a peer device. */
|
||||
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_evt_t;
|
||||
|
||||
/**
|
||||
* @brief Ble scan result event type, to indicate the
|
||||
* result is scan response or advertising data or other
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_BLE_EVT_CONN_ADV = 0x00, /*!< Connectable undirected advertising (ADV_IND) */
|
||||
ESP_BLE_EVT_CONN_DIR_ADV = 0x01, /*!< Connectable directed advertising (ADV_DIRECT_IND) */
|
||||
ESP_BLE_EVT_DISC_ADV = 0x02, /*!< Scannable undirected advertising (ADV_SCAN_IND) */
|
||||
ESP_BLE_EVT_NON_CONN_ADV = 0x03, /*!< Non connectable undirected advertising (ADV_NONCONN_IND) */
|
||||
ESP_BLE_EVT_SCAN_RSP = 0x04, /*!< Scan Response (SCAN_RSP) */
|
||||
} esp_ble_evt_type_t;
|
||||
|
||||
/**
|
||||
* @brief Gap callback parameters union
|
||||
*/
|
||||
typedef union {
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT
|
||||
*/
|
||||
struct ble_adv_data_cmpl_evt_param {
|
||||
esp_bt_status_t status; /*!< Indicate the set advertising data operation success status */
|
||||
} adv_data_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT
|
||||
*/
|
||||
struct ble_scan_rsp_data_cmpl_evt_param {
|
||||
esp_bt_status_t status; /*!< Indicate the set scan response data operation success status */
|
||||
} scan_rsp_data_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT
|
||||
*/
|
||||
struct ble_scan_param_cmpl_evt_param {
|
||||
esp_bt_status_t status; /*!< Indicate the set scan param operation success status */
|
||||
} scan_param_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_SCAN_RESULT_EVT
|
||||
*/
|
||||
struct ble_scan_result_evt_param {
|
||||
esp_gap_search_evt_t search_evt; /*!< Search event type */
|
||||
esp_bd_addr_t bda; /*!< Bluetooth device address which has been searched */
|
||||
esp_bt_dev_type_t dev_type; /*!< Device type */
|
||||
esp_ble_addr_type_t ble_addr_type; /*!< Ble device address type */
|
||||
esp_ble_evt_type_t ble_evt_type; /*!< Ble scan result event type */
|
||||
int rssi; /*!< Searched device's RSSI */
|
||||
uint8_t ble_adv[ESP_BLE_ADV_DATA_LEN_MAX + ESP_BLE_SCAN_RSP_DATA_LEN_MAX]; /*!< Received EIR */
|
||||
int flag; /*!< Advertising data flag bit */
|
||||
int num_resps; /*!< Scan result number */
|
||||
} scan_rst; /*!< Event parameter of ESP_GAP_BLE_SCAN_RESULT_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT
|
||||
*/
|
||||
struct ble_adv_data_raw_cmpl_evt_param {
|
||||
esp_bt_status_t status; /*!< Indicate the set raw advertising data operation success status */
|
||||
} adv_data_raw_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_DATA_RAW_SET_COMPLETE_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT
|
||||
*/
|
||||
struct ble_scan_rsp_data_raw_cmpl_evt_param {
|
||||
esp_bt_status_t status; /*!< Indicate the set raw advertising data operation success status */
|
||||
} scan_rsp_data_raw_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_RSP_DATA_RAW_SET_COMPLETE_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_ADV_START_COMPLETE_EVT
|
||||
*/
|
||||
struct ble_adv_start_cmpl_evt_param {
|
||||
esp_bt_status_t status; /*!< Indicate advertising start operation success status */
|
||||
} adv_start_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_START_COMPLETE_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_SCAN_START_COMPLETE_EVT
|
||||
*/
|
||||
struct ble_scan_start_cmpl_evt_param {
|
||||
esp_bt_status_t status; /*!< Indicate scan start operation success status */
|
||||
} scan_start_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_START_COMPLETE_EVT */
|
||||
} esp_ble_gap_cb_param_t;
|
||||
|
||||
/**
|
||||
* @brief GAP callback function type
|
||||
* @param event : Event type
|
||||
* @param param : Point to callback parameter, currently is union type
|
||||
*/
|
||||
typedef void (* esp_gap_ble_cb_t)(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param);
|
||||
|
||||
/**
|
||||
* @brief This function is called to occur gap event, such as scan result
|
||||
*
|
||||
* @param[in] callback: callback function
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gap_register_callback(esp_gap_ble_cb_t callback);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to override the BTA default ADV parameters.
|
||||
*
|
||||
* @param[in] adv_data: Pointer to User defined ADV data structure. This
|
||||
* memory space can not be freed until callback of config_adv_data
|
||||
* is received.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gap_config_adv_data (esp_ble_adv_data_t *adv_data);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to set scan parameters
|
||||
*
|
||||
* @param[in] scan_params: Pointer to User defined scan_params data structure. This
|
||||
* memory space can not be freed until callback of set_scan_params
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gap_set_scan_params(esp_ble_scan_params_t *scan_params);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This procedure keep the device scanning the peer device which advertising on the air
|
||||
*
|
||||
* @param[in] duration: Keeping the scanning time, the unit is second.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gap_start_scanning(uint32_t duration);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function call to stop the device scanning the peer device which advertising on the air
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gap_stop_scanning(void);
|
||||
|
||||
/**
|
||||
* @brief This function is called to start advertising.
|
||||
*
|
||||
* @param[in] adv_params: pointer to User defined adv_params data structure.
|
||||
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gap_start_advertising (esp_ble_adv_params_t *adv_params);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to stop advertising.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gap_stop_advertising(void);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Update connection parameters, can only be used when connection is up.
|
||||
*
|
||||
* @param[in] params - connection update parameters
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gap_update_conn_params(esp_ble_conn_update_params_t *params);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is to set maximum LE data packet size
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gap_set_pkt_data_len(esp_bd_addr_t remote_device, uint16_t tx_data_length);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function set the random address for the application
|
||||
*
|
||||
* @param[in] rand_addr: the random address which should be setting
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gap_set_rand_addr(esp_bd_addr_t rand_addr);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable/disable privacy on the local device
|
||||
*
|
||||
* @param[in] privacy_enable - enable/disable privacy on remote device.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gap_config_local_privacy (bool privacy_enable);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set device name to the local device
|
||||
*
|
||||
* @param[in] name - device name.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gap_set_device_name(const char *name);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to get ADV data for a specific type.
|
||||
*
|
||||
* @param[in] adv_data - pointer of ADV data which to be resolved
|
||||
* @param[in] type - finding ADV data type
|
||||
* @param[out] length - return the length of ADV data not including type
|
||||
*
|
||||
* @return - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
uint8_t *esp_ble_resolve_adv_data(uint8_t *adv_data, uint8_t type, uint8_t *length);
|
||||
|
||||
/**
|
||||
* @brief This function is called to set raw advertising data. User need to fill
|
||||
* ADV data by self.
|
||||
*
|
||||
* @param[in] raw_data : raw advertising data
|
||||
* @param[in] raw_data_len : raw advertising data length , less than 31 bytes
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gap_config_adv_data_raw(uint8_t *raw_data, uint32_t raw_data_len);
|
||||
|
||||
/**
|
||||
* @brief This function is called to set raw scan response data. User need to fill
|
||||
* scan response data by self.
|
||||
*
|
||||
* @param[in] raw_data : raw scan response data
|
||||
* @param[in] raw_data_len : raw scan response data length , less than 31 bytes
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*/
|
||||
esp_err_t esp_ble_gap_config_scan_rsp_data_raw(uint8_t *raw_data, uint32_t raw_data_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_GAP_BLE_API_H__ */
|
||||
384
components/bt/bluedroid/api/include/esp_gatt_defs.h
Normal file
384
components/bt/bluedroid/api/include/esp_gatt_defs.h
Normal file
@@ -0,0 +1,384 @@
|
||||
// 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 __ESP_GATT_DEFS_H__
|
||||
#define __ESP_GATT_DEFS_H__
|
||||
|
||||
#include "esp_bt_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// GATT INVALID UUID
|
||||
#define ESP_GATT_ILLEGAL_UUID 0
|
||||
/// GATT INVALID HANDLE
|
||||
#define ESP_GATT_ILLEGAL_HANDLE 0
|
||||
/// GATT attribute max handle
|
||||
#define ESP_GATT_ATTR_HANDLE_MAX 100
|
||||
|
||||
|
||||
/**@{
|
||||
* All "ESP_GATT_UUID_xxx" is attribute types
|
||||
*/
|
||||
#define ESP_GATT_UUID_IMMEDIATE_ALERT_SVC 0x1802 /* Immediate alert Service*/
|
||||
#define ESP_GATT_UUID_LINK_LOSS_SVC 0x1803 /* Link Loss Service*/
|
||||
#define ESP_GATT_UUID_TX_POWER_SVC 0x1804 /* TX Power Service*/
|
||||
#define ESP_GATT_UUID_CURRENT_TIME_SVC 0x1805 /* Current Time Service Service*/
|
||||
#define ESP_GATT_UUID_REF_TIME_UPDATE_SVC 0x1806 /* Reference Time Update Service*/
|
||||
#define ESP_GATT_UUID_NEXT_DST_CHANGE_SVC 0x1807 /* Next DST Change Service*/
|
||||
#define ESP_GATT_UUID_GLUCOSE_SVC 0x1808 /* Glucose Service*/
|
||||
#define ESP_GATT_UUID_HEALTH_THERMOM_SVC 0x1809 /* Health Thermometer Service*/
|
||||
#define ESP_GATT_UUID_DEVICE_INFO_SVC 0x180A /* Device Information Service*/
|
||||
#define ESP_GATT_UUID_HEART_RATE_SVC 0x180D /* Heart Rate Service*/
|
||||
#define ESP_GATT_UUID_PHONE_ALERT_STATUS_SVC 0x180E /* Phone Alert Status Service*/
|
||||
#define ESP_GATT_UUID_BATTERY_SERVICE_SVC 0x180F /* Battery Service*/
|
||||
#define ESP_GATT_UUID_BLOOD_PRESSURE_SVC 0x1810 /* Blood Pressure Service*/
|
||||
#define ESP_GATT_UUID_ALERT_NTF_SVC 0x1811 /* Alert Notification Service*/
|
||||
#define ESP_GATT_UUID_HID_SVC 0x1812 /* HID Service*/
|
||||
#define ESP_GATT_UUID_SCAN_PARAMETERS_SVC 0x1813 /* Scan Parameters Service*/
|
||||
#define ESP_GATT_UUID_RUNNING_SPEED_CADENCE_SVC 0x1814 /* Running Speed and Cadence Service*/
|
||||
#define ESP_GATT_UUID_CYCLING_SPEED_CADENCE_SVC 0x1816 /* Cycling Speed and Cadence Service*/
|
||||
#define ESP_GATT_UUID_CYCLING_POWER_SVC 0x1818 /* Cycling Power Service*/
|
||||
#define ESP_GATT_UUID_LOCATION_AND_NAVIGATION_SVC 0x1819 /* Location and Navigation Service*/
|
||||
#define ESP_GATT_UUID_USER_DATA_SVC 0x181C /* User Data Service*/
|
||||
#define ESP_GATT_UUID_WEIGHT_SCALE_SVC 0x181D /* Weight Scale Service*/
|
||||
|
||||
#define ESP_GATT_UUID_PRI_SERVICE 0x2800
|
||||
#define ESP_GATT_UUID_SEC_SERVICE 0x2801
|
||||
#define ESP_GATT_UUID_INCLUDE_SERVICE 0x2802
|
||||
#define ESP_GATT_UUID_CHAR_DECLARE 0x2803 /* Characteristic Declaration*/
|
||||
|
||||
#define ESP_GATT_UUID_CHAR_EXT_PROP 0x2900 /* Characteristic Extended Properties */
|
||||
#define ESP_GATT_UUID_CHAR_DESCRIPTION 0x2901 /* Characteristic User Description*/
|
||||
#define ESP_GATT_UUID_CHAR_CLIENT_CONFIG 0x2902 /* Client Characteristic Configuration */
|
||||
#define ESP_GATT_UUID_CHAR_SRVR_CONFIG 0x2903 /* Server Characteristic Configuration */
|
||||
#define ESP_GATT_UUID_CHAR_PRESENT_FORMAT 0x2904 /* Characteristic Presentation Format*/
|
||||
#define ESP_GATT_UUID_CHAR_AGG_FORMAT 0x2905 /* Characteristic Aggregate Format*/
|
||||
#define ESP_GATT_UUID_CHAR_VALID_RANGE 0x2906 /* Characteristic Valid Range */
|
||||
#define ESP_GATT_UUID_EXT_RPT_REF_DESCR 0x2907
|
||||
#define ESP_GATT_UUID_RPT_REF_DESCR 0x2908
|
||||
|
||||
/* GAP Profile Attributes */
|
||||
#define ESP_GATT_UUID_GAP_DEVICE_NAME 0x2A00
|
||||
#define ESP_GATT_UUID_GAP_ICON 0x2A01
|
||||
#define ESP_GATT_UUID_GAP_PREF_CONN_PARAM 0x2A04
|
||||
#define ESP_GATT_UUID_GAP_CENTRAL_ADDR_RESOL 0x2AA6
|
||||
|
||||
/* Attribute Profile Attribute UUID */
|
||||
#define ESP_GATT_UUID_GATT_SRV_CHGD 0x2A05
|
||||
|
||||
/* Link ESP_Loss Service */
|
||||
#define ESP_GATT_UUID_ALERT_LEVEL 0x2A06 /* Alert Level */
|
||||
#define ESP_GATT_UUID_TX_POWER_LEVEL 0x2A07 /* TX power level */
|
||||
|
||||
/* Current Time Service */
|
||||
#define ESP_GATT_UUID_CURRENT_TIME 0x2A2B /* Current Time */
|
||||
#define ESP_GATT_UUID_LOCAL_TIME_INFO 0x2A0F /* Local time info */
|
||||
#define ESP_GATT_UUID_REF_TIME_INFO 0x2A14 /* reference time information */
|
||||
|
||||
/* Network availability Profile */
|
||||
#define ESP_GATT_UUID_NW_STATUS 0x2A18 /* network availability status */
|
||||
#define ESP_GATT_UUID_NW_TRIGGER 0x2A1A /* Network availability trigger */
|
||||
|
||||
/* Phone alert */
|
||||
#define ESP_GATT_UUID_ALERT_STATUS 0x2A3F /* alert status */
|
||||
#define ESP_GATT_UUID_RINGER_CP 0x2A40 /* ringer control point */
|
||||
#define ESP_GATT_UUID_RINGER_SETTING 0x2A41 /* ringer setting */
|
||||
|
||||
/* Glucose Service */
|
||||
#define ESP_GATT_UUID_GM_MEASUREMENT 0x2A18
|
||||
#define ESP_GATT_UUID_GM_CONTEXT 0x2A34
|
||||
#define ESP_GATT_UUID_GM_CONTROL_POINT 0x2A52
|
||||
#define ESP_GATT_UUID_GM_FEATURE 0x2A51
|
||||
|
||||
/* device information characteristic */
|
||||
#define ESP_GATT_UUID_SYSTEM_ID 0x2A23
|
||||
#define ESP_GATT_UUID_MODEL_NUMBER_STR 0x2A24
|
||||
#define ESP_GATT_UUID_SERIAL_NUMBER_STR 0x2A25
|
||||
#define ESP_GATT_UUID_FW_VERSION_STR 0x2A26
|
||||
#define ESP_GATT_UUID_HW_VERSION_STR 0x2A27
|
||||
#define ESP_GATT_UUID_SW_VERSION_STR 0x2A28
|
||||
#define ESP_GATT_UUID_MANU_NAME 0x2A29
|
||||
#define ESP_GATT_UUID_IEEE_DATA 0x2A2A
|
||||
#define ESP_GATT_UUID_PNP_ID 0x2A50
|
||||
|
||||
/* HID characteristics */
|
||||
#define ESP_GATT_UUID_HID_INFORMATION 0x2A4A
|
||||
#define ESP_GATT_UUID_HID_REPORT_MAP 0x2A4B
|
||||
#define ESP_GATT_UUID_HID_CONTROL_POINT 0x2A4C
|
||||
#define ESP_GATT_UUID_HID_REPORT 0x2A4D
|
||||
#define ESP_GATT_UUID_HID_PROTO_MODE 0x2A4E
|
||||
#define ESP_GATT_UUID_HID_BT_KB_INPUT 0x2A22
|
||||
#define ESP_GATT_UUID_HID_BT_KB_OUTPUT 0x2A32
|
||||
#define ESP_GATT_UUID_HID_BT_MOUSE_INPUT 0x2A33
|
||||
|
||||
/// Heart Rate Measurement
|
||||
#define ESP_GATT_HEART_RATE_MEAS 0x2A37
|
||||
/// Body Sensor Location
|
||||
#define ESP_GATT_BODY_SENSOR_LOCATION 0x2A38
|
||||
/// Heart Rate Control Point
|
||||
#define ESP_GATT_HEART_RATE_CNTL_POINT 0x2A39
|
||||
|
||||
/* Battery Service characteristics */
|
||||
#define ESP_GATT_UUID_BATTERY_LEVEL 0x2A19
|
||||
|
||||
/* Sensor Service */
|
||||
#define ESP_GATT_UUID_SC_CONTROL_POINT 0x2A55
|
||||
#define ESP_GATT_UUID_SENSOR_LOCATION 0x2A5D
|
||||
|
||||
/* Runners speed and cadence service */
|
||||
#define ESP_GATT_UUID_RSC_MEASUREMENT 0x2A53
|
||||
#define ESP_GATT_UUID_RSC_FEATURE 0x2A54
|
||||
|
||||
/* Cycling speed and cadence service */
|
||||
#define ESP_GATT_UUID_CSC_MEASUREMENT 0x2A5B
|
||||
#define ESP_GATT_UUID_CSC_FEATURE 0x2A5C
|
||||
|
||||
/* Scan ESP_Parameter characteristics */
|
||||
#define ESP_GATT_UUID_SCAN_INT_WINDOW 0x2A4F
|
||||
#define ESP_GATT_UUID_SCAN_REFRESH 0x2A31
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/// Attribute write data type from the client
|
||||
typedef enum {
|
||||
ESP_GATT_PREP_WRITE_CANCEL = 0x00, /*!< Prepare write cancel */
|
||||
ESP_GATT_PREP_WRITE_EXEC = 0x01, /*!< Prepare write execute */
|
||||
} esp_gatt_prep_write_type;
|
||||
|
||||
/**
|
||||
* @brief GATT success code and error codes
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_GATT_OK = 0x0,
|
||||
ESP_GATT_INVALID_HANDLE = 0x01, /* 0x0001 */
|
||||
ESP_GATT_READ_NOT_PERMIT = 0x02, /* 0x0002 */
|
||||
ESP_GATT_WRITE_NOT_PERMIT = 0x03, /* 0x0003 */
|
||||
ESP_GATT_INVALID_PDU = 0x04, /* 0x0004 */
|
||||
ESP_GATT_INSUF_AUTHENTICATION = 0x05, /* 0x0005 */
|
||||
ESP_GATT_REQ_NOT_SUPPORTED = 0x06, /* 0x0006 */
|
||||
ESP_GATT_INVALID_OFFSET = 0x07, /* 0x0007 */
|
||||
ESP_GATT_INSUF_AUTHORIZATION = 0x08, /* 0x0008 */
|
||||
ESP_GATT_PREPARE_Q_FULL = 0x09, /* 0x0009 */
|
||||
ESP_GATT_NOT_FOUND = 0x0a, /* 0x000a */
|
||||
ESP_GATT_NOT_LONG = 0x0b, /* 0x000b */
|
||||
ESP_GATT_INSUF_KEY_SIZE = 0x0c, /* 0x000c */
|
||||
ESP_GATT_INVALID_ATTR_LEN = 0x0d, /* 0x000d */
|
||||
ESP_GATT_ERR_UNLIKELY = 0x0e, /* 0x000e */
|
||||
ESP_GATT_INSUF_ENCRYPTION = 0x0f, /* 0x000f */
|
||||
ESP_GATT_UNSUPPORT_GRP_TYPE = 0x10, /* 0x0010 */
|
||||
ESP_GATT_INSUF_RESOURCE = 0x11, /* 0x0011 */
|
||||
|
||||
ESP_GATT_NO_RESOURCES = 0x80, /* 0x80 */
|
||||
ESP_GATT_INTERNAL_ERROR = 0x81, /* 0x81 */
|
||||
ESP_GATT_WRONG_STATE = 0x82, /* 0x82 */
|
||||
ESP_GATT_DB_FULL = 0x83, /* 0x83 */
|
||||
ESP_GATT_BUSY = 0x84, /* 0x84 */
|
||||
ESP_GATT_ERROR = 0x85, /* 0x85 */
|
||||
ESP_GATT_CMD_STARTED = 0x86, /* 0x86 */
|
||||
ESP_GATT_ILLEGAL_PARAMETER = 0x87, /* 0x87 */
|
||||
ESP_GATT_PENDING = 0x88, /* 0x88 */
|
||||
ESP_GATT_AUTH_FAIL = 0x89, /* 0x89 */
|
||||
ESP_GATT_MORE = 0x8a, /* 0x8a */
|
||||
ESP_GATT_INVALID_CFG = 0x8b, /* 0x8b */
|
||||
ESP_GATT_SERVICE_STARTED = 0x8c, /* 0x8c */
|
||||
ESP_GATT_ENCRYPED_MITM = ESP_GATT_OK,
|
||||
ESP_GATT_ENCRYPED_NO_MITM = 0x8d, /* 0x8d */
|
||||
ESP_GATT_NOT_ENCRYPTED = 0x8e, /* 0x8e */
|
||||
ESP_GATT_CONGESTED = 0x8f, /* 0x8f */
|
||||
ESP_GATT_DUP_REG = 0x90, /* 0x90 */
|
||||
ESP_GATT_ALREADY_OPEN = 0x91, /* 0x91 */
|
||||
ESP_GATT_CANCEL = 0x92, /* 0x92 */
|
||||
|
||||
/* 0xE0 ~ 0xFC reserved for future use */
|
||||
ESP_GATT_CCC_CFG_ERR = 0xfd, /* 0xFD Client Characteristic Configuration Descriptor Improperly Configured */
|
||||
ESP_GATT_PRC_IN_PROGRESS = 0xfe, /* 0xFE Procedure Already in progress */
|
||||
ESP_GATT_OUT_OF_RANGE = 0xff, /* 0xFFAttribute value out of range */
|
||||
} esp_gatt_status_t;
|
||||
|
||||
/**
|
||||
* @brief Gatt Connection reason enum
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_GATT_CONN_UNKNOWN = 0, /*!< Gatt connection unknown */
|
||||
ESP_GATT_CONN_L2C_FAILURE = 1, /*!< General L2cap failure */
|
||||
ESP_GATT_CONN_TIMEOUT = 0x08, /*!< Connection timeout */
|
||||
ESP_GATT_CONN_TERMINATE_PEER_USER = 0x13, /*!< Connection terminate by peer user */
|
||||
ESP_GATT_CONN_TERMINATE_LOCAL_HOST = 0x16, /*!< Connectionterminated by local host */
|
||||
ESP_GATT_CONN_FAIL_ESTABLISH = 0x3e, /*!< Connection fail to establish */
|
||||
ESP_GATT_CONN_LMP_TIMEOUT = 0x22, /*!< Connection fail for LMP response tout */
|
||||
ESP_GATT_CONN_CONN_CANCEL = 0x0100, /*!< L2CAP connection cancelled */
|
||||
ESP_GATT_CONN_NONE = 0x0101 /*!< No connection to cancel */
|
||||
} esp_gatt_conn_reason_t;
|
||||
|
||||
/**
|
||||
* @brief Gatt id, include uuid and instance id
|
||||
*/
|
||||
typedef struct {
|
||||
esp_bt_uuid_t uuid; /*!< UUID */
|
||||
uint8_t inst_id; /*!< Instance id */
|
||||
} __attribute__((packed)) esp_gatt_id_t;
|
||||
|
||||
/**
|
||||
* @brief Gatt service id, include id
|
||||
* (uuid and instance id) and primary flag
|
||||
*/
|
||||
typedef struct {
|
||||
esp_gatt_id_t id; /*!< Gatt id, include uuid and instance */
|
||||
bool is_primary; /*!< This service is primary or not */
|
||||
} __attribute__((packed)) esp_gatt_srvc_id_t;
|
||||
|
||||
/**
|
||||
* @brief Gatt authentication request type
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_GATT_AUTH_REQ_NONE = 0,
|
||||
ESP_GATT_AUTH_REQ_NO_MITM = 1, /* unauthenticated encryption */
|
||||
ESP_GATT_AUTH_REQ_MITM = 2, /* authenticated encryption */
|
||||
ESP_GATT_AUTH_REQ_SIGNED_NO_MITM = 3,
|
||||
ESP_GATT_AUTH_REQ_SIGNED_MITM = 4,
|
||||
} esp_gatt_auth_req_t;
|
||||
|
||||
/**
|
||||
* @brief Attribute permissions
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_GATT_PERM_READ = (1 << 0), /* bit 0 - 0x0001 */
|
||||
ESP_GATT_PERM_READ_ENCRYPTED = (1 << 1), /* bit 1 - 0x0002 */
|
||||
ESP_GATT_PERM_READ_ENC_MITM = (1 << 2), /* bit 2 - 0x0004 */
|
||||
ESP_GATT_PERM_WRITE = (1 << 4), /* bit 4 - 0x0010 */
|
||||
ESP_GATT_PERM_WRITE_ENCRYPTED = (1 << 5), /* bit 5 - 0x0020 */
|
||||
ESP_GATT_PERM_WRITE_ENC_MITM = (1 << 6), /* bit 6 - 0x0040 */
|
||||
ESP_GATT_PERM_WRITE_SIGNED = (1 << 7), /* bit 7 - 0x0080 */
|
||||
ESP_GATT_PERM_WRITE_SIGNED_MITM = (1 << 8), /* bit 8 - 0x0100 */
|
||||
} esp_gatt_perm_t;
|
||||
|
||||
/* definition of characteristic properties */
|
||||
typedef enum {
|
||||
ESP_GATT_CHAR_PROP_BIT_BROADCAST = (1 << 0), /* 0x01 */
|
||||
ESP_GATT_CHAR_PROP_BIT_READ = (1 << 1), /* 0x02 */
|
||||
ESP_GATT_CHAR_PROP_BIT_WRITE_NR = (1 << 2), /* 0x04 */
|
||||
ESP_GATT_CHAR_PROP_BIT_WRITE = (1 << 3), /* 0x08 */
|
||||
ESP_GATT_CHAR_PROP_BIT_NOTIFY = (1 << 4), /* 0x10 */
|
||||
ESP_GATT_CHAR_PROP_BIT_INDICATE = (1 << 5), /* 0x20 */
|
||||
ESP_GATT_CHAR_PROP_BIT_AUTH = (1 << 6), /* 0x40 */
|
||||
ESP_GATT_CHAR_PROP_BIT_EXT_PROP = (1 << 7), /* 0x80 */
|
||||
} esp_gatt_char_prop_t;
|
||||
|
||||
/// GATT maximum attribute length
|
||||
#define ESP_GATT_MAX_ATTR_LEN 600 //as same as GATT_MAX_ATTR_LEN
|
||||
|
||||
|
||||
/**
|
||||
* @brief Attribute description (used to create database)
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t uuid_length; /*!< UUID length */
|
||||
uint8_t *uuid_p; /*!< UUID value */
|
||||
uint16_t perm; /*!< Attribute permission */
|
||||
uint16_t max_length; /*!< Maximum length of the element*/
|
||||
uint16_t length; /*!< Current length of the element*/
|
||||
uint8_t *value; /*!< Element value array*/
|
||||
} esp_attr_desc_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief attribute auto respose flag
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
#define ESP_GATT_RSP_BY_APP 0
|
||||
#define ESP_GATT_AUTO_RSP 1
|
||||
uint8_t auto_rsp; /*!< need the app response to the client if need_rsp set to 1*/
|
||||
} esp_attr_control_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief attribute type added to the gatt server database
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
esp_attr_control_t attr_control; /*!< The attribue control type*/
|
||||
esp_attr_desc_t att_desc; /*!< The attribue type*/
|
||||
} esp_gatts_attr_db_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief set the attribute value type
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t attr_max_len; /*!< attribute max value length */
|
||||
uint16_t attr_len; /*!< attribute current value length */
|
||||
uint8_t *attr_value; /*!< the pointer to attribute value */
|
||||
} esp_attr_value_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Gatt include service entry element
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t start_hdl; /*!< Gatt start handle value of included service */
|
||||
uint16_t end_hdl; /*!< Gatt end handle value of included service */
|
||||
uint16_t uuid; /*!< Gatt attribute value UUID of included service */
|
||||
} esp_gatts_incl_svc_desc_t; /*!< Gatt include service entry element */
|
||||
|
||||
/**
|
||||
* @brief Gatt include 128 bit service entry element
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t start_hdl; /*!< Gatt start handle value of included 128 bit service */
|
||||
uint16_t end_hdl; /*!< Gatt end handle value of included 128 bit service */
|
||||
} esp_gatts_incl128_svc_desc_t; /*!< Gatt include 128 bit service entry element */
|
||||
|
||||
|
||||
|
||||
|
||||
/// Gatt attribute value
|
||||
typedef struct {
|
||||
uint8_t value[ESP_GATT_MAX_ATTR_LEN]; /*!< Gatt attribute value */
|
||||
uint16_t handle; /*!< Gatt attribute handle */
|
||||
uint16_t offset; /*!< Gatt attribute value offset */
|
||||
uint16_t len; /*!< Gatt attribute value length */
|
||||
uint8_t auth_req; /*!< Gatt authentication request */
|
||||
} esp_gatt_value_t;
|
||||
|
||||
/// GATT remote read request response type
|
||||
typedef union {
|
||||
esp_gatt_value_t attr_value; /*!< Gatt attribute structure */
|
||||
uint16_t handle; /*!< Gatt attribute handle */
|
||||
} esp_gatt_rsp_t;
|
||||
|
||||
/**
|
||||
* @brief Gatt write type
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_GATT_WRITE_TYPE_NO_RSP = 1, /*!< Gatt write attribute need no response */
|
||||
ESP_GATT_WRITE_TYPE_RSP, /*!< Gatt write attribute need remote response */
|
||||
} esp_gatt_write_type_t;
|
||||
|
||||
#define ESP_GATT_IF_NONE 0xff /*!< If callback report gattc_if/gatts_if as this macro, means this event is not correspond to any app */
|
||||
|
||||
typedef uint8_t esp_gatt_if_t; /*!< Gatt interface type, different application on GATT client use different gatt_if */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_GATT_DEFS_H__ */
|
||||
607
components/bt/bluedroid/api/include/esp_gattc_api.h
Normal file
607
components/bt/bluedroid/api/include/esp_gattc_api.h
Normal file
@@ -0,0 +1,607 @@
|
||||
// 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 __ESP_GATTC_API_H__
|
||||
#define __ESP_GATTC_API_H__
|
||||
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_gatt_defs.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// GATT Client callback function events
|
||||
typedef enum {
|
||||
ESP_GATTC_REG_EVT = 0, /*!< When GATT client is registered, the event comes */
|
||||
ESP_GATTC_UNREG_EVT = 1, /*!< When GATT client is unregistered, the event comes */
|
||||
ESP_GATTC_OPEN_EVT = 2, /*!< When GATT connection is set up, the event comes */
|
||||
ESP_GATTC_READ_CHAR_EVT = 3, /*!< When GATT characteristic is read, the event comes */
|
||||
ESP_GATTC_WRITE_CHAR_EVT = 4, /*!< When GATT characteristic write operation completes, the event comes */
|
||||
ESP_GATTC_CLOSE_EVT = 5, /*!< When GATT connection is closed, the event comes */
|
||||
ESP_GATTC_SEARCH_CMPL_EVT = 6, /*!< When GATT service discovery is completed, the event comes */
|
||||
ESP_GATTC_SEARCH_RES_EVT = 7, /*!< When GATT service discovery result is got, the event comes */
|
||||
ESP_GATTC_READ_DESCR_EVT = 8, /*!< When GATT characteristic descriptor read completes, the event comes */
|
||||
ESP_GATTC_WRITE_DESCR_EVT = 9, /*!< When GATT characteristic descriptor write completes, the event comes */
|
||||
ESP_GATTC_NOTIFY_EVT = 10, /*!< When GATT notification or indication arrives, the event comes */
|
||||
ESP_GATTC_PREP_WRITE_EVT = 11, /*!< When GATT prepare-write operation completes, the event comes */
|
||||
ESP_GATTC_EXEC_EVT = 12, /*!< When write execution completes, the event comes */
|
||||
ESP_GATTC_ACL_EVT = 13, /*!< When ACL connection is up, the event comes */
|
||||
ESP_GATTC_CANCEL_OPEN_EVT = 14, /*!< When GATT client ongoing connection is cancelled, the event comes */
|
||||
ESP_GATTC_SRVC_CHG_EVT = 15, /*!< When "service changed" occurs, the event comes */
|
||||
ESP_GATTC_ENC_CMPL_CB_EVT = 17, /*!< When encryption procedure completes, the event comes */
|
||||
ESP_GATTC_CFG_MTU_EVT = 18, /*!< When configuration of MTU completes, the event comes */
|
||||
ESP_GATTC_ADV_DATA_EVT = 19, /*!< When advertising of data, the event comes */
|
||||
ESP_GATTC_MULT_ADV_ENB_EVT = 20, /*!< When multi-advertising is enabled, the event comes */
|
||||
ESP_GATTC_MULT_ADV_UPD_EVT = 21, /*!< When multi-advertising parameters are updated, the event comes */
|
||||
ESP_GATTC_MULT_ADV_DATA_EVT = 22, /*!< When multi-advertising data arrives, the event comes */
|
||||
ESP_GATTC_MULT_ADV_DIS_EVT = 23, /*!< When multi-advertising is disabled, the event comes */
|
||||
ESP_GATTC_CONGEST_EVT = 24, /*!< When GATT connection congestion comes, the event comes */
|
||||
ESP_GATTC_BTH_SCAN_ENB_EVT = 25, /*!< When batch scan is enabled, the event comes */
|
||||
ESP_GATTC_BTH_SCAN_CFG_EVT = 26, /*!< When batch scan storage is configured, the event comes */
|
||||
ESP_GATTC_BTH_SCAN_RD_EVT = 27, /*!< When Batch scan read event is reported, the event comes */
|
||||
ESP_GATTC_BTH_SCAN_THR_EVT = 28, /*!< When Batch scan threshold is set, the event comes */
|
||||
ESP_GATTC_BTH_SCAN_PARAM_EVT = 29, /*!< When Batch scan parameters are set, the event comes */
|
||||
ESP_GATTC_BTH_SCAN_DIS_EVT = 30, /*!< When Batch scan is disabled, the event comes */
|
||||
ESP_GATTC_SCAN_FLT_CFG_EVT = 31, /*!< When Scan filter configuration completes, the event comes */
|
||||
ESP_GATTC_SCAN_FLT_PARAM_EVT = 32, /*!< When Scan filter parameters are set, the event comes */
|
||||
ESP_GATTC_SCAN_FLT_STATUS_EVT = 33, /*!< When Scan filter status is reported, the event comes */
|
||||
ESP_GATTC_ADV_VSC_EVT = 34, /*!< When advertising vendor spec content event is reported, the event comes */
|
||||
ESP_GATTC_GET_CHAR_EVT = 35, /*!< When characteristic is got from GATT server, the event comes */
|
||||
ESP_GATTC_GET_DESCR_EVT = 36, /*!< When characteristic descriptor is got from GATT server, the event comes */
|
||||
ESP_GATTC_GET_INCL_SRVC_EVT = 37, /*!< When included service is got from GATT server, the event comes */
|
||||
ESP_GATTC_REG_FOR_NOTIFY_EVT = 38, /*!< When register for notification of a service completes, the event comes */
|
||||
ESP_GATTC_UNREG_FOR_NOTIFY_EVT = 39, /*!< When unregister for notification of a service completes, the event comes */
|
||||
} esp_gattc_cb_event_t;
|
||||
|
||||
/// Maximum Transmission Unit used in GATT
|
||||
#define ESP_GATT_DEF_BLE_MTU_SIZE 23
|
||||
|
||||
/// Maximum Transmission Unit allowed in GATT
|
||||
#define ESP_GATT_MAX_MTU_SIZE 517
|
||||
|
||||
/**
|
||||
* @brief Gatt client callback parameters union
|
||||
*/
|
||||
typedef union {
|
||||
/**
|
||||
* @brief ESP_GATTC_REG_EVT
|
||||
*/
|
||||
struct gattc_reg_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t app_id; /*!< Application id which input in register API */
|
||||
} reg; /*!< Gatt client callback param of ESP_GATTC_REG_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_OPEN_EVT
|
||||
*/
|
||||
struct gattc_open_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
|
||||
uint16_t mtu; /*!< MTU size */
|
||||
} open; /*!< Gatt client callback param of ESP_GATTC_OPEN_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_CLOSE_EVT
|
||||
*/
|
||||
struct gattc_close_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
|
||||
esp_gatt_conn_reason_t reason; /*!< The reason of gatt connection close */
|
||||
} close; /*!< Gatt client callback param of ESP_GATTC_CLOSE_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_CFG_MTU_EVT
|
||||
*/
|
||||
struct gattc_cfg_mtu_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
uint16_t mtu; /*!< MTU size */
|
||||
} cfg_mtu; /*!< Gatt client callback param of ESP_GATTC_CFG_MTU_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_SEARCH_CMPL_EVT
|
||||
*/
|
||||
struct gattc_search_cmpl_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
} search_cmpl; /*!< Gatt client callback param of ESP_GATTC_SEARCH_CMPL_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_SEARCH_RES_EVT
|
||||
*/
|
||||
struct gattc_search_res_evt_param {
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
|
||||
} search_res; /*!< Gatt client callback param of ESP_GATTC_SEARCH_RES_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_READ_CHAR_EVT, ESP_GATTC_READ_DESCR_EVT
|
||||
*/
|
||||
struct gattc_read_char_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
|
||||
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
|
||||
esp_gatt_id_t descr_id; /*!< Descriptor id, include descriptor uuid and other information */
|
||||
uint8_t *value; /*!< Characteristic value */
|
||||
uint16_t value_type; /*!< Characteristic value type */
|
||||
uint16_t value_len; /*!< Characteristic value length */
|
||||
} read; /*!< Gatt client callback param of ESP_GATTC_READ_CHAR_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_WRITE_CHAR_EVT, ESP_GATTC_PREP_WRITE_EVT, ESP_GATTC_WRITE_DESCR_EVT
|
||||
*/
|
||||
struct gattc_write_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
|
||||
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
|
||||
esp_gatt_id_t descr_id; /*!< Descriptor id, include descriptor uuid and other information */
|
||||
} write; /*!< Gatt client callback param of ESP_GATTC_WRITE_DESCR_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_EXEC_EVT
|
||||
*/
|
||||
struct gattc_exec_cmpl_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
} exec_cmpl; /*!< Gatt client callback param of ESP_GATTC_EXEC_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_NOTIFY_EVT
|
||||
*/
|
||||
struct gattc_notify_evt_param {
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
|
||||
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
|
||||
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
|
||||
esp_gatt_id_t descr_id; /*!< Descriptor id, include descriptor uuid and other information */
|
||||
uint16_t value_len; /*!< Notify attribute value */
|
||||
uint8_t *value; /*!< Notify attribute value */
|
||||
bool is_notify; /*!< True means notify, false means indicate */
|
||||
} notify; /*!< Gatt client callback param of ESP_GATTC_NOTIFY_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_SRVC_CHG_EVT
|
||||
*/
|
||||
struct gattc_srvc_chg_evt_param {
|
||||
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
|
||||
} srvc_chg; /*!< Gatt client callback param of ESP_GATTC_SRVC_CHG_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_CONGEST_EVT
|
||||
*/
|
||||
struct gattc_congest_evt_param {
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
bool congested; /*!< Congested or not */
|
||||
} congest; /*!< Gatt client callback param of ESP_GATTC_CONGEST_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_GET_CHAR_EVT
|
||||
*/
|
||||
struct gattc_get_char_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
|
||||
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
|
||||
esp_gatt_char_prop_t char_prop; /*!< Characteristic property */
|
||||
} get_char; /*!< Gatt client callback param of ESP_GATTC_GET_CHAR_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_GET_DESCR_EVT
|
||||
*/
|
||||
struct gattc_get_descr_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
|
||||
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
|
||||
esp_gatt_id_t descr_id; /*!< Descriptor id, include descriptor uuid and other information */
|
||||
} get_descr; /*!< Gatt client callback param of ESP_GATTC_GET_DESCR_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_GET_INCL_SRVC_EVT
|
||||
*/
|
||||
struct gattc_get_incl_srvc_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
|
||||
esp_gatt_srvc_id_t incl_srvc_id;/*!< Included service id, include service uuid and other information */
|
||||
} get_incl_srvc; /*!< Gatt client callback param of ESP_GATTC_GET_INCL_SRVC_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_REG_FOR_NOTIFY_EVT
|
||||
*/
|
||||
struct gattc_reg_for_notify_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
|
||||
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
|
||||
} reg_for_notify; /*!< Gatt client callback param of ESP_GATTC_REG_FOR_NOTIFY_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_UNREG_FOR_NOTIFY_EVT
|
||||
*/
|
||||
struct gattc_unreg_for_notify_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
|
||||
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
|
||||
} unreg_for_notify; /*!< Gatt client callback param of ESP_GATTC_UNREG_FOR_NOTIFY_EVT */
|
||||
|
||||
|
||||
} esp_ble_gattc_cb_param_t; /*!< GATT client callback parameter union type */
|
||||
|
||||
/**
|
||||
* @brief GATT Client callback function type
|
||||
* @param event : Event type
|
||||
* @param gatts_if : GATT client access interface, normally
|
||||
* different gattc_if correspond to different profile
|
||||
* @param param : Point to callback parameter, currently is union type
|
||||
*/
|
||||
typedef void (* esp_gattc_cb_t)(esp_gattc_cb_event_t event, esp_gatt_if_t gattc_if, esp_ble_gattc_cb_param_t *param);
|
||||
|
||||
/**
|
||||
* @brief This function is called to register application callbacks
|
||||
* with GATTC module.
|
||||
*
|
||||
* @param[in] callback : pointer to the application callback function.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gattc_register_callback(esp_gattc_cb_t callback);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to register application callbacks
|
||||
* with GATTC module.
|
||||
*
|
||||
* @param[in] app_id : Application Identify (UUID), for different application
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gattc_app_register(uint16_t app_id);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to unregister an application
|
||||
* from GATTC module.
|
||||
*
|
||||
* @param[in] gattc_if: Gatt client access interface.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gattc_app_unregister(esp_gatt_if_t gattc_if);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Open a direct connection or add a background auto connection
|
||||
*
|
||||
* @param[in] gattc_if: Gatt client access interface.
|
||||
* @param[in] remote_bda: remote device bluetooth device address.
|
||||
* @param[in] is_direct: direct connection or background auto connection
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gattc_open(esp_gatt_if_t gattc_if, esp_bd_addr_t remote_bda, bool is_direct);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Close a connection to a GATT server.
|
||||
*
|
||||
* @param[in] gattc_if: Gatt client access interface.
|
||||
* @param[in] conn_id: connection ID to be closed.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gattc_close (esp_gatt_if_t gattc_if, uint16_t conn_id);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Configure the MTU size in the GATT channel. This can be done
|
||||
* only once per connection.
|
||||
*
|
||||
* @param[in] gattc_if: Gatt client access interface.
|
||||
* @param[in] conn_id: connection ID.
|
||||
* @param[in] mtu: desired MTU size to use.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gattc_config_mtu (esp_gatt_if_t gattc_if, uint16_t conn_id, uint16_t mtu);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to request a GATT service discovery
|
||||
* on a GATT server. This function report service search result
|
||||
* by a callback event, and followed by a service search complete
|
||||
* event.
|
||||
*
|
||||
* @param[in] gattc_if: Gatt client access interface.
|
||||
* @param[in] conn_id: connection ID.
|
||||
* @param[in] filter_uuid: a UUID of the service application is interested in.
|
||||
* If Null, discover for all services.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gattc_search_service(esp_gatt_if_t gattc_if, uint16_t conn_id, esp_bt_uuid_t *filter_uuid);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to find the first characteristic of the
|
||||
* service on the given server.
|
||||
*
|
||||
* @param[in] gattc_if: Gatt client access interface.
|
||||
* @param[in] conn_id: connection ID which identify the server.
|
||||
* @param[in] srvc_id: service ID
|
||||
* @param[in] start_char_id: the start characteristic ID
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gattc_get_characteristic(esp_gatt_if_t gattc_if,
|
||||
uint16_t conn_id,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *start_char_id);
|
||||
|
||||
/**
|
||||
* @brief This function is called to find the descriptor of the
|
||||
* service on the given server.
|
||||
*
|
||||
* @param[in] gattc_if: Gatt client access interface.
|
||||
* @param[in] conn_id: connection ID which identify the server.
|
||||
* @param[in] srvc_id: the service ID of which the characteristic is belonged to.
|
||||
* @param[in] char_id: Characteristic ID, if NULL find the first available
|
||||
* characteristic.
|
||||
* @param[in] start_descr_id: the start descriptor id
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gattc_get_descriptor(esp_gatt_if_t gattc_if,
|
||||
uint16_t conn_id,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id,
|
||||
esp_gatt_id_t *start_descr_id);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to find the first characteristic of the
|
||||
* service on the given server.
|
||||
*
|
||||
* @param[in] gattc_if: Gatt client access interface.
|
||||
* @param[in] conn_id: connection ID which identify the server.
|
||||
* @param[in] srvc_id: the service ID of which the characteristic is belonged to.
|
||||
* @param[in] start_incl_srvc_id: the start include service id
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gattc_get_included_service(esp_gatt_if_t gattc_if,
|
||||
uint16_t conn_id,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_srvc_id_t *start_incl_srvc_id);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to read a service's characteristics of
|
||||
* the given characteristic ID
|
||||
*
|
||||
* @param[in] gattc_if: Gatt client access interface.
|
||||
* @param[in] conn_id : connection ID.
|
||||
* @param[in] srvc_id : service ID.
|
||||
* @param[in] char_id : characteristic ID to read.
|
||||
* @param[in] auth_req : authenticate request type
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gattc_read_char (esp_gatt_if_t gattc_if,
|
||||
uint16_t conn_id,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id,
|
||||
esp_gatt_auth_req_t auth_req);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to read a characteristics descriptor.
|
||||
*
|
||||
* @param[in] gattc_if: Gatt client access interface.
|
||||
* @param[in] conn_id : connection ID.
|
||||
* @param[in] srvc_id : service ID.
|
||||
* @param[in] char_id : characteristic ID to read.
|
||||
* @param[in] descr_id : characteristic descriptor ID to read.
|
||||
* @param[in] auth_req : authenticate request type
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gattc_read_char_descr (esp_gatt_if_t gattc_if,
|
||||
uint16_t conn_id,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id,
|
||||
esp_gatt_id_t *descr_id,
|
||||
esp_gatt_auth_req_t auth_req);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to write characteristic value.
|
||||
*
|
||||
* @param[in] gattc_if: Gatt client access interface.
|
||||
* @param[in] conn_id : connection ID.
|
||||
* @param[in] srvc_id : service ID.
|
||||
* @param[in] char_id : characteristic ID to write.
|
||||
* @param[in] value_len: length of the value to be written.
|
||||
* @param[in] value : the value to be written.
|
||||
* @param[in] write_type : the type of attribute write operation.
|
||||
* @param[in] auth_req : authentication request.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gattc_write_char( esp_gatt_if_t gattc_if,
|
||||
uint16_t conn_id,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id,
|
||||
uint16_t value_len,
|
||||
uint8_t *value,
|
||||
esp_gatt_write_type_t write_type,
|
||||
esp_gatt_auth_req_t auth_req);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to write characteristic descriptor value.
|
||||
*
|
||||
* @param[in] gattc_if: Gatt client access interface.
|
||||
* @param[in] conn_id : connection ID
|
||||
* @param[in] srvc_id : service ID.
|
||||
* @param[in] char_id : characteristic ID.
|
||||
* @param[in] descr_id : characteristic descriptor ID to write.
|
||||
* @param[in] value_len: length of the value to be written.
|
||||
* @param[in] value : the value to be written.
|
||||
* @param[in] write_type : the type of attribute write operation.
|
||||
* @param[in] auth_req : authentication request.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if,
|
||||
uint16_t conn_id,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id,
|
||||
esp_gatt_id_t *descr_id,
|
||||
uint16_t value_len,
|
||||
uint8_t *value,
|
||||
esp_gatt_write_type_t write_type,
|
||||
esp_gatt_auth_req_t auth_req);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to prepare write a characteristic value.
|
||||
*
|
||||
* @param[in] gattc_if: Gatt client access interface.
|
||||
* @param[in] conn_id : connection ID.
|
||||
* @param[in] srvc_id : service ID.
|
||||
* @param[in] char_id : GATT characteristic ID of the service.
|
||||
* @param[in] offset : offset of the write value.
|
||||
* @param[in] value_len: length of the value to be written.
|
||||
* @param[in] value : the value to be written.
|
||||
* @param[in] auth_req : authentication request.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gattc_prepare_write(esp_gatt_if_t gattc_if,
|
||||
uint16_t conn_id,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id,
|
||||
uint16_t offset,
|
||||
uint16_t value_len,
|
||||
uint8_t *value,
|
||||
esp_gatt_auth_req_t auth_req);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to execute write a prepare write sequence.
|
||||
*
|
||||
* @param[in] gattc_if: Gatt client access interface.
|
||||
* @param[in] conn_id : connection ID.
|
||||
* @param[in] is_execute : execute or cancel.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gattc_execute_write (esp_gatt_if_t gattc_if, uint16_t conn_id, bool is_execute);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to register for notification of a service.
|
||||
*
|
||||
* @param[in] gattc_if: Gatt client access interface.
|
||||
* @param[in] server_bda : target GATT server.
|
||||
* @param[in] srvc_id : pointer to GATT service ID.
|
||||
* @param[in] char_id : pointer to GATT characteristic ID.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: registration succeeds
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_gatt_status_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gattc_if,
|
||||
esp_bd_addr_t server_bda,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to de-register for notification of a service.
|
||||
*
|
||||
* @param[in] gattc_if: Gatt client access interface.
|
||||
* @param[in] server_bda : target GATT server.
|
||||
* @param[in] srvc_id : pointer to GATT service ID.
|
||||
* @param[in] char_id : pointer to GATT characteristic ID.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: unregister succeeds
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_gatt_status_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gattc_if,
|
||||
esp_bd_addr_t server_bda,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_GATTC_API_H__ */
|
||||
542
components/bt/bluedroid/api/include/esp_gatts_api.h
Normal file
542
components/bt/bluedroid/api/include/esp_gatts_api.h
Normal file
@@ -0,0 +1,542 @@
|
||||
// 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 __ESP_GATTS_API_H__
|
||||
#define __ESP_GATTS_API_H__
|
||||
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_gatt_defs.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// GATT Server callback function events
|
||||
typedef enum {
|
||||
ESP_GATTS_REG_EVT = 0, /*!< When register application id, the event comes */
|
||||
ESP_GATTS_READ_EVT = 1, /*!< When gatt client request read operation, the event comes */
|
||||
ESP_GATTS_WRITE_EVT = 2, /*!< When gatt client request write operation, the event comes */
|
||||
ESP_GATTS_EXEC_WRITE_EVT = 3, /*!< When gatt client request execute write, the event comes */
|
||||
ESP_GATTS_MTU_EVT = 4, /*!< When set mtu complete, the event comes */
|
||||
ESP_GATTS_CONF_EVT = 5, /*!< When receive confirm, the event comes */
|
||||
ESP_GATTS_UNREG_EVT = 6, /*!< When unregister application id, the event comes */
|
||||
ESP_GATTS_CREATE_EVT = 7, /*!< When create service complete, the event comes */
|
||||
ESP_GATTS_ADD_INCL_SRVC_EVT = 8, /*!< When add included service complete, the event comes */
|
||||
ESP_GATTS_ADD_CHAR_EVT = 9, /*!< When add characteristic complete, the event comes */
|
||||
ESP_GATTS_ADD_CHAR_DESCR_EVT = 10, /*!< When add descriptor complete, the event comes */
|
||||
ESP_GATTS_DELETE_EVT = 11, /*!< When delete service complete, the event comes */
|
||||
ESP_GATTS_START_EVT = 12, /*!< When start service complete, the event comes */
|
||||
ESP_GATTS_STOP_EVT = 13, /*!< When stop service complete, the event comes */
|
||||
ESP_GATTS_CONNECT_EVT = 14, /*!< When gatt client connect, the event comes */
|
||||
ESP_GATTS_DISCONNECT_EVT = 15, /*!< When gatt client disconnect, the event comes */
|
||||
ESP_GATTS_OPEN_EVT = 16, /*!< When connect to peer, the event comes */
|
||||
ESP_GATTS_CANCEL_OPEN_EVT = 17, /*!< When disconnect from peer, the event comes */
|
||||
ESP_GATTS_CLOSE_EVT = 18, /*!< When gatt server close, the event comes */
|
||||
ESP_GATTS_LISTEN_EVT = 19, /*!< When gatt listen to be connected the event comes */
|
||||
ESP_GATTS_CONGEST_EVT = 20, /*!< When congest happen, the event comes */
|
||||
/* following is extra event */
|
||||
ESP_GATTS_RESPONSE_EVT = 21, /*!< When gatt send response complete, the event comes */
|
||||
ESP_GATTS_CREAT_ATTR_TAB_EVT = 22,
|
||||
ESP_GATTS_SET_ATTR_VAL_EVT = 23,
|
||||
} esp_gatts_cb_event_t;
|
||||
|
||||
/**
|
||||
* @brief Gatt server callback parameters union
|
||||
*/
|
||||
typedef union {
|
||||
/**
|
||||
* @brief ESP_GATTS_REG_EVT
|
||||
*/
|
||||
struct gatts_reg_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t app_id; /*!< Application id which input in register API */
|
||||
} reg; /*!< Gatt server callback param of ESP_GATTS_REG_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_READ_EVT
|
||||
*/
|
||||
struct gatts_read_evt_param {
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
uint32_t trans_id; /*!< Transfer id */
|
||||
esp_bd_addr_t bda; /*!< The bluetooth device address which been read */
|
||||
uint16_t handle; /*!< The attribute handle */
|
||||
uint16_t offset; /*!< Offset of the value, if the value is too long */
|
||||
bool is_long; /*!< The value is too long or not */
|
||||
bool need_rsp; /*!< The read operation need to do response */
|
||||
} read; /*!< Gatt server callback param of ESP_GATTS_READ_EVT */
|
||||
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_WRITE_EVT
|
||||
*/
|
||||
struct gatts_write_evt_param {
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
uint32_t trans_id; /*!< Transfer id */
|
||||
esp_bd_addr_t bda; /*!< The bluetooth device address which been written */
|
||||
uint16_t handle; /*!< The attribute handle */
|
||||
uint16_t offset; /*!< Offset of the value, if the value is too long */
|
||||
bool need_rsp; /*!< The write operation need to do response */
|
||||
bool is_prep; /*!< This write operation is prepare write */
|
||||
uint16_t len; /*!< The write attribute value length */
|
||||
uint8_t *value; /*!< The write attribute value */
|
||||
} write; /*!< Gatt server callback param of ESP_GATTS_WRITE_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_EXEC_WRITE_EVT
|
||||
*/
|
||||
struct gatts_exec_write_evt_param {
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
uint32_t trans_id; /*!< Transfer id */
|
||||
esp_bd_addr_t bda; /*!< The bluetooth device address which been written */
|
||||
#define ESP_GATT_PREP_WRITE_CANCEL 0x00 /*!< Prepare write flag to indicate cancel prepare write */
|
||||
#define ESP_GATT_PREP_WRITE_EXEC 0x01 /*!< Prepare write flag to indicate execute prepare write */
|
||||
uint8_t exec_write_flag; /*!< Execute write flag */
|
||||
} exec_write; /*!< Gatt server callback param of ESP_GATTS_EXEC_WRITE_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_MTU_EVT
|
||||
*/
|
||||
struct gatts_mtu_evt_param {
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
uint16_t mtu; /*!< MTU size */
|
||||
} mtu; /*!< Gatt server callback param of ESP_GATTS_MTU_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_CONF_EVT
|
||||
*/
|
||||
struct gatts_conf_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
} conf; /*!< Gatt server callback param of ESP_GATTS_CONF_EVT (confirm) */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_UNREG_EVT
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_CREATE_EVT
|
||||
*/
|
||||
struct gatts_create_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t service_handle; /*!< Service attribute handle */
|
||||
esp_gatt_srvc_id_t service_id; /*!< Service id, include service uuid and other information */
|
||||
} create; /*!< Gatt server callback param of ESP_GATTS_CREATE_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_ADD_INCL_SRVC_EVT
|
||||
*/
|
||||
struct gatts_add_incl_srvc_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t attr_handle; /*!< Included service attribute handle */
|
||||
uint16_t service_handle; /*!< Service attribute handle */
|
||||
} add_incl_srvc; /*!< Gatt server callback param of ESP_GATTS_ADD_INCL_SRVC_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_ADD_CHAR_EVT
|
||||
*/
|
||||
struct gatts_add_char_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t attr_handle; /*!< Characteristic attribute handle */
|
||||
uint16_t service_handle; /*!< Service attribute handle */
|
||||
esp_bt_uuid_t char_uuid; /*!< Characteristic uuid */
|
||||
} add_char; /*!< Gatt server callback param of ESP_GATTS_ADD_CHAR_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_ADD_CHAR_DESCR_EVT
|
||||
*/
|
||||
struct gatts_add_char_descr_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t attr_handle; /*!< Descriptor attribute handle */
|
||||
uint16_t service_handle; /*!< Service attribute handle */
|
||||
esp_bt_uuid_t char_uuid; /*!< Characteristic uuid */
|
||||
} add_char_descr; /*!< Gatt server callback param of ESP_GATTS_ADD_CHAR_DESCR_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_DELETE_EVT
|
||||
*/
|
||||
struct gatts_delete_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t service_handle; /*!< Service attribute handle */
|
||||
} del; /*!< Gatt server callback param of ESP_GATTS_DELETE_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_START_EVT
|
||||
*/
|
||||
struct gatts_start_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t service_handle; /*!< Service attribute handle */
|
||||
} start; /*!< Gatt server callback param of ESP_GATTS_START_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_STOP_EVT
|
||||
*/
|
||||
struct gatts_stop_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t service_handle; /*!< Service attribute handle */
|
||||
} stop; /*!< Gatt server callback param of ESP_GATTS_STOP_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_CONNECT_EVT
|
||||
*/
|
||||
struct gatts_connect_evt_param {
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
|
||||
bool is_connected; /*!< Indicate it is connected or not */
|
||||
} connect; /*!< Gatt server callback param of ESP_GATTS_CONNECT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_DISCONNECT_EVT
|
||||
*/
|
||||
struct gatts_disconnect_evt_param {
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
|
||||
bool is_connected; /*!< Indicate it is connected or not */
|
||||
} disconnect; /*!< Gatt server callback param of ESP_GATTS_DISCONNECT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_OPEN_EVT
|
||||
*/
|
||||
/**
|
||||
* @brief ESP_GATTS_CANCEL_OPEN_EVT
|
||||
*/
|
||||
/**
|
||||
* @brief ESP_GATTS_CLOSE_EVT
|
||||
*/
|
||||
/**
|
||||
* @brief ESP_GATTS_LISTEN_EVT
|
||||
*/
|
||||
/**
|
||||
* @brief ESP_GATTS_CONGEST_EVT
|
||||
*/
|
||||
struct gatts_congest_evt_param {
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
bool congested; /*!< Congested or not */
|
||||
} congest; /*!< Gatt server callback param of ESP_GATTS_CONGEST_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_RESPONSE_EVT
|
||||
*/
|
||||
struct gatts_rsp_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t handle; /*!< Attribute handle which send response */
|
||||
} rsp; /*!< Gatt server callback param of ESP_GATTS_RESPONSE_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_CREAT_ATTR_TAB_EVT
|
||||
*/
|
||||
struct gatts_add_attr_tab_evt_param{
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
esp_bt_uuid_t svc_uuid; /*!< Service uuid type */
|
||||
uint16_t num_handle; /*!< The number of the attribute handle to be added to the gatts database */
|
||||
uint16_t *handles; /*!< The number to the handles */
|
||||
} add_attr_tab; /*!< Gatt server callback param of ESP_GATTS_CREAT_ATTR_TAB_EVT */
|
||||
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_SET_ATTR_VAL_EVT
|
||||
*/
|
||||
struct gatts_set_attr_val_evt_param{
|
||||
uint16_t srvc_handle; /*!< The service handle */
|
||||
uint16_t attr_handle; /*!< The attribute handle */
|
||||
esp_gatt_status_t status; /*!< Operation status*/
|
||||
} set_attr_val; /*!< Gatt server callback param of ESP_GATTS_SET_ATTR_VAL_EVT */
|
||||
|
||||
} esp_ble_gatts_cb_param_t;
|
||||
|
||||
/**
|
||||
* @brief GATT Server callback function type
|
||||
* @param event : Event type
|
||||
* @param gatts_if : GATT server access interface, normally
|
||||
* different gatts_if correspond to different profile
|
||||
* @param param : Point to callback parameter, currently is union type
|
||||
*/
|
||||
typedef void (* esp_gatts_cb_t)(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
|
||||
|
||||
/**
|
||||
* @brief This function is called to register application callbacks
|
||||
* with BTA GATTS module.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_register_callback(esp_gatts_cb_t callback);
|
||||
|
||||
/**
|
||||
* @brief This function is called to register application identifier
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_app_register(uint16_t app_id);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief unregister with GATT Server.
|
||||
*
|
||||
* @param[in] gatts_if: GATT server access interface
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_app_unregister(esp_gatt_if_t gatts_if);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Create a service. When service creation is done, a callback
|
||||
* event BTA_GATTS_CREATE_SRVC_EVT is called to report status
|
||||
* and service ID to the profile. The service ID obtained in
|
||||
* the callback function needs to be used when adding included
|
||||
* service and characteristics/descriptors into the service.
|
||||
*
|
||||
* @param[in] gatts_if: GATT server access interface
|
||||
* @param[in] service_id: service ID.
|
||||
* @param[in] num_handle: number of handle requested for this service.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_create_service(esp_gatt_if_t gatts_if,
|
||||
esp_gatt_srvc_id_t *service_id, uint16_t num_handle);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Create a service attribute tab.
|
||||
* @param[in] gatts_attr_db: the pointer to the service attr tab
|
||||
* @param[in] gatts_if: GATT server access interface
|
||||
* @param[in] max_nb_attr: the number of attribute to be added to the service database.
|
||||
* @param[in] srvc_inst_id: the instance id of the service
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_create_attr_tab(const esp_gatts_attr_db_t *gatts_attr_db,
|
||||
esp_gatt_if_t gatts_if,
|
||||
uint8_t max_nb_attr,
|
||||
uint8_t srvc_inst_id);
|
||||
/**
|
||||
* @brief This function is called to add an included service. After included
|
||||
* service is included, a callback event BTA_GATTS_ADD_INCL_SRVC_EVT
|
||||
* is reported the included service ID.
|
||||
*
|
||||
* @param[in] service_handle: service handle to which this included service is to
|
||||
* be added.
|
||||
* @param[in] included_service_handle: the service ID to be included.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_add_included_service(uint16_t service_handle, uint16_t included_service_handle);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to add a characteristic into a service.
|
||||
*
|
||||
* @param[in] service_handle: service handle to which this included service is to
|
||||
* be added.
|
||||
* @param[in] char_uuid : Characteristic UUID.
|
||||
* @param[in] perm : Characteristic value declaration attribute permission.
|
||||
* @param[in] property : Characteristic Properties
|
||||
* @param[in] char_val : Characteristic value
|
||||
* @param[in] control : attribute response control byte
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_add_char(uint16_t service_handle, esp_bt_uuid_t *char_uuid,
|
||||
esp_gatt_perm_t perm, esp_gatt_char_prop_t property, esp_attr_value_t *char_val,
|
||||
esp_attr_control_t *control);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to add characteristic descriptor. When
|
||||
* it's done, a callback event BTA_GATTS_ADD_DESCR_EVT is called
|
||||
* to report the status and an ID number for this descriptor.
|
||||
*
|
||||
* @param[in] service_handle: service handle to which this characteristic descriptor is to
|
||||
* be added.
|
||||
* @param[in] perm: descriptor access permission.
|
||||
* @param[in] descr_uuid: descriptor UUID.
|
||||
* @param[in] char_descr_val : Characteristic descriptor value
|
||||
* @param[in] control : attribute response control byte
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_add_char_descr (uint16_t service_handle,
|
||||
esp_bt_uuid_t *descr_uuid,
|
||||
esp_gatt_perm_t perm, esp_attr_value_t *char_descr_val,
|
||||
esp_attr_control_t *control);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to delete a service. When this is done,
|
||||
* a callback event BTA_GATTS_DELETE_EVT is report with the status.
|
||||
*
|
||||
* @param[in] service_handle: service_handle to be deleted.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_delete_service(uint16_t service_handle);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to start a service.
|
||||
*
|
||||
* @param[in] service_handle: the service handle to be started.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_start_service(uint16_t service_handle);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to stop a service.
|
||||
*
|
||||
* @param[in] service_handle - service to be topped.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_stop_service(uint16_t service_handle);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Send indicate or notify to GATT client.
|
||||
* Set param need_confirm as false will send notification, otherwise indication.
|
||||
*
|
||||
* @param[in] gatts_if: GATT server access interface
|
||||
* @param[in] conn_id - connection id to indicate.
|
||||
* @param[in] attr_handle - attribute handle to indicate.
|
||||
* @param[in] value_len - indicate value length.
|
||||
* @param[in] value: value to indicate.
|
||||
* @param[in] need_confirm - Whether a confirmation is required.
|
||||
* false sends a GATT notification, true sends a GATT indication.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_send_indicate(esp_gatt_if_t gatts_if, uint16_t conn_id, uint16_t attr_handle,
|
||||
uint16_t value_len, uint8_t *value, bool need_confirm);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to send a response to a request.
|
||||
*
|
||||
* @param[in] gatts_if: GATT server access interface
|
||||
* @param[in] conn_id - connection identifier.
|
||||
* @param[in] trans_id - transfer id
|
||||
* @param[in] status - response status
|
||||
* @param[in] rsp - response data.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_send_response(esp_gatt_if_t gatts_if, uint16_t conn_id, uint32_t trans_id,
|
||||
esp_gatt_status_t status, esp_gatt_rsp_t *rsp);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to set the attribute value by the application
|
||||
*
|
||||
* @param[in] attr_handle: the attribute handle which to be set
|
||||
* @param[in] length: the value length
|
||||
* @param[in] value: the pointer to the attribute value
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_set_attr_value(uint16_t attr_handle, uint16_t length, const uint8_t *value);
|
||||
|
||||
/**
|
||||
* @brief Retrieve attribute value
|
||||
*
|
||||
* @param[in] attr_handle: Attribute handle.
|
||||
* @param[out] length: pointer to the attribute value length
|
||||
* @param[out] value: Pointer to attribute value payload, the value cannot be modified by user
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, const uint8_t **value);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Open a direct open connection or add a background auto connection
|
||||
*
|
||||
* @param[in] gatts_if: GATT server access interface
|
||||
* @param[in] remote_bda: remote device bluetooth device address.
|
||||
* @param[in] is_direct: direct connection or background auto connection
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_open(esp_gatt_if_t gatts_if, esp_bd_addr_t remote_bda, bool is_direct);
|
||||
|
||||
/**
|
||||
* @brief Close a connection a remote device.
|
||||
*
|
||||
* @param[in] gatts_if: GATT server access interface
|
||||
* @param[in] conn_id: connection ID to be closed.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_close(esp_gatt_if_t gatts_if, uint16_t conn_id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_GATTS_API_H__ */
|
||||
5534
components/bt/bluedroid/bta/dm/bta_dm_act.c
Normal file
5534
components/bt/bluedroid/bta/dm/bta_dm_act.c
Normal file
File diff suppressed because it is too large
Load Diff
2253
components/bt/bluedroid/bta/dm/bta_dm_api.c
Normal file
2253
components/bt/bluedroid/bta/dm/bta_dm_api.c
Normal file
File diff suppressed because it is too large
Load Diff
580
components/bt/bluedroid/bta/dm/bta_dm_cfg.c
Normal file
580
components/bt/bluedroid/bta/dm/bta_dm_cfg.c
Normal file
@@ -0,0 +1,580 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains compile-time configurable constants for the device
|
||||
* manager.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "bt_target.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_api.h"
|
||||
#include "bta_dm_int.h"
|
||||
// #include "bta_jv_api.h"
|
||||
|
||||
#ifndef BTA_DM_LINK_POLICY_SETTINGS
|
||||
#define BTA_DM_LINK_POLICY_SETTINGS (HCI_ENABLE_MASTER_SLAVE_SWITCH | HCI_ENABLE_HOLD_MODE | HCI_ENABLE_SNIFF_MODE | HCI_ENABLE_PARK_MODE)
|
||||
#endif
|
||||
|
||||
/* page timeout in 625uS */
|
||||
#ifndef BTA_DM_PAGE_TIMEOUT
|
||||
#define BTA_DM_PAGE_TIMEOUT 8192
|
||||
#endif
|
||||
|
||||
/* link supervision timeout in 625uS (5 secs) */
|
||||
#ifndef BTA_DM_LINK_TIMEOUT
|
||||
#define BTA_DM_LINK_TIMEOUT 8000
|
||||
#endif
|
||||
|
||||
/* TRUE to avoid scatternet when av is streaming (be the master) */
|
||||
#ifndef BTA_DM_AVOID_SCATTER_A2DP
|
||||
#define BTA_DM_AVOID_SCATTER_A2DP TRUE
|
||||
#endif
|
||||
|
||||
/* For Insight, PM cfg lookup tables are runtime configurable (to allow tweaking of params for power consumption measurements) */
|
||||
#ifndef BTE_SIM_APP
|
||||
#define tBTA_DM_PM_TYPE_QUALIFIER const
|
||||
#else
|
||||
#define tBTA_DM_PM_TYPE_QUALIFIER
|
||||
#endif
|
||||
|
||||
|
||||
const tBTA_DM_CFG bta_dm_cfg = {
|
||||
/* mobile phone COD */
|
||||
BTA_DM_COD,
|
||||
/* link policy settings */
|
||||
BTA_DM_LINK_POLICY_SETTINGS,
|
||||
/* page timeout in 625uS */
|
||||
BTA_DM_PAGE_TIMEOUT,
|
||||
/* link supervision timeout in 625uS*/
|
||||
BTA_DM_LINK_TIMEOUT,
|
||||
/* TRUE to avoid scatternet when av is streaming (be the master) */
|
||||
BTA_DM_AVOID_SCATTER_A2DP
|
||||
};
|
||||
|
||||
#ifndef BTA_DM_SCATTERNET
|
||||
/* By default, allow partial scatternet */
|
||||
#define BTA_DM_SCATTERNET BTA_DM_PARTIAL_SCATTERNET
|
||||
#endif
|
||||
|
||||
#ifndef BTA_HH_ROLE
|
||||
/* By default, do not specify HH role (backward compatibility) */
|
||||
#define BTA_HH_ROLE BTA_ANY_ROLE
|
||||
#endif
|
||||
|
||||
#ifndef BTA_AV_ROLE
|
||||
/* By default, AV role (backward BTA_MASTER_ROLE_PREF) */
|
||||
#define BTA_AV_ROLE BTA_MASTER_ROLE_PREF
|
||||
#endif
|
||||
|
||||
#ifndef BTA_PANU_ROLE
|
||||
/* By default, AV role (backward BTA_MASTER_ROLE_PREF) */
|
||||
#define BTA_PANU_ROLE BTA_SLAVE_ROLE_ONLY
|
||||
#endif
|
||||
#define BTA_DM_NUM_RM_ENTRY 6
|
||||
|
||||
/* appids for PAN used by insight sample application
|
||||
these have to be same as defined in btui_int.h */
|
||||
#define BTUI_PAN_ID_PANU 0
|
||||
#define BTUI_PAN_ID_NAP 1
|
||||
#define BTUI_PAN_ID_GN 2
|
||||
|
||||
/* First element is always for SYS:
|
||||
app_id = # of entries table, cfg is
|
||||
device scatternet support */
|
||||
const tBTA_DM_RM bta_dm_rm_cfg[] = {
|
||||
{BTA_ID_SYS, BTA_DM_NUM_RM_ENTRY, BTA_DM_SCATTERNET},
|
||||
{BTA_ID_PAN, BTUI_PAN_ID_NAP, BTA_ANY_ROLE},
|
||||
{BTA_ID_PAN, BTUI_PAN_ID_GN, BTA_ANY_ROLE},
|
||||
{BTA_ID_PAN, BTA_APP_ID_PAN_MULTI, BTA_MASTER_ROLE_ONLY},
|
||||
{BTA_ID_PAN, BTUI_PAN_ID_PANU, BTA_PANU_ROLE},
|
||||
{BTA_ID_HH, BTA_ALL_APP_ID, BTA_HH_ROLE},
|
||||
{BTA_ID_AV, BTA_ALL_APP_ID, BTA_AV_ROLE}
|
||||
};
|
||||
|
||||
|
||||
tBTA_DM_CFG *p_bta_dm_cfg = (tBTA_DM_CFG *) &bta_dm_cfg;
|
||||
|
||||
tBTA_DM_RM *p_bta_dm_rm_cfg = (tBTA_DM_RM *) &bta_dm_rm_cfg;
|
||||
|
||||
#if BLE_INCLUDED == TRUE
|
||||
# define BTA_DM_NUM_PM_ENTRY 21 /* number of entries in bta_dm_pm_cfg except the first */
|
||||
# define BTA_DM_NUM_PM_SPEC 15 /* number of entries in bta_dm_pm_spec */
|
||||
#else
|
||||
# define BTA_DM_NUM_PM_ENTRY 19 /* number of entries in bta_dm_pm_cfg except the first */
|
||||
# define BTA_DM_NUM_PM_SPEC 13 /* number of entries in bta_dm_pm_spec */
|
||||
#endif
|
||||
|
||||
tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_CFG bta_dm_pm_cfg[BTA_DM_NUM_PM_ENTRY + 1] = {
|
||||
{BTA_ID_SYS, BTA_DM_NUM_PM_ENTRY, 0}, /* reserved: specifies length of this table. */
|
||||
{BTA_ID_AG, BTA_ALL_APP_ID, 0}, /* ag uses first spec table for app id 0 */
|
||||
{BTA_ID_CT, 1, 1}, /* ct (BTA_ID_CT,APP ID=1) spec table */
|
||||
{BTA_ID_CG, BTA_ALL_APP_ID, 1}, /* cg resue ct spec table */
|
||||
{BTA_ID_DG, BTA_ALL_APP_ID, 2}, /* dg spec table */
|
||||
{BTA_ID_AV, BTA_ALL_APP_ID, 4}, /* av spec table */
|
||||
{BTA_ID_AVK, BTA_ALL_APP_ID, 12}, /* avk spec table */
|
||||
{BTA_ID_FTC, BTA_ALL_APP_ID, 6}, /* ftc spec table */
|
||||
{BTA_ID_FTS, BTA_ALL_APP_ID, 7}, /* fts spec table */
|
||||
{BTA_ID_HD, BTA_ALL_APP_ID, 3}, /* hd spec table */
|
||||
{BTA_ID_HH, BTA_ALL_APP_ID, 5}, /* hh spec table */
|
||||
{BTA_ID_PBC, BTA_ALL_APP_ID, 2}, /* reuse dg spec table */
|
||||
{BTA_ID_PBS, BTA_ALL_APP_ID, 7}, /* reuse fts spec table */
|
||||
{BTA_ID_OPC, BTA_ALL_APP_ID, 6}, /* reuse ftc spec table */
|
||||
{BTA_ID_OPS, BTA_ALL_APP_ID, 7}, /* reuse fts spec table */
|
||||
{BTA_ID_MSE, BTA_ALL_APP_ID, 7}, /* reuse fts spec table */
|
||||
// {BTA_ID_JV, BTA_JV_PM_ID_1, 6}, /* app BTA_JV_PM_ID_1, reuse ftc spec table */
|
||||
// {BTA_ID_JV, BTA_ALL_APP_ID, 7}, /* reuse fts spec table */
|
||||
{BTA_ID_HL, BTA_ALL_APP_ID, 8}, /* reuse fts spec table */
|
||||
{BTA_ID_PAN, BTUI_PAN_ID_PANU, 9}, /* PANU spec table */
|
||||
{BTA_ID_PAN, BTUI_PAN_ID_NAP, 10}, /* NAP spec table */
|
||||
{BTA_ID_HS, BTA_ALL_APP_ID, 11} /* HS spec table */
|
||||
#if BLE_INCLUDED == TRUE
|
||||
, {BTA_ID_GATTC, BTA_ALL_APP_ID, 13} /* gattc spec table */
|
||||
, {BTA_ID_GATTS, BTA_ALL_APP_ID, 14} /* gatts spec table */
|
||||
#endif
|
||||
};
|
||||
|
||||
tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
|
||||
/* AG : 0 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
|
||||
{{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 */
|
||||
{{BTA_DM_PM_SNIFF_SCO_OPEN_IDX, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_RETRY, 7000}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* CT, CG : 1 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_PARK, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open park */
|
||||
{{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 */
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open sniff */
|
||||
{{BTA_DM_PM_PARK, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close park */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_RETRY, 5000}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* DG, PBC : 2 */
|
||||
{
|
||||
(BTA_DM_PM_ACTIVE), /* no power saving mode allowed */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF, 5000}, {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_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF, 1000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* HD : 3 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR3), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF_HD_ACTIVE_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
|
||||
{{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 */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF_HD_IDLE_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_SNIFF_HD_ACTIVE_IDX, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* AV : 4 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF), /* allow sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
|
||||
{{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 */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* HH : 5 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR1), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF_HH_OPEN_IDX, BTA_DM_PM_HH_OPEN_DELAY}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
|
||||
{{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 */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close, used for HH suspend */
|
||||
{{BTA_DM_PM_SNIFF_HH_IDLE_IDX, BTA_DM_PM_HH_IDLE_DELAY}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_SNIFF_HH_ACTIVE_IDX, BTA_DM_PM_HH_ACTIVE_DELAY}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* FTC, OPC, JV : 6 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF), /* allow sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_ACTIVE, 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_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* FTS, PBS, OPS, MSE, BTA_JV_PM_ID_1 : 7 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF), /* allow sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_ACTIVE, 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_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, BTA_FTS_OPS_IDLE_TO_SNIFF_DELAY_MS}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* HL : 8 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF), /* allow sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
|
||||
{{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 */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* PANU : 9 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF), /* allow sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_ACTIVE, 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_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* NAP : 10 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF), /* allow sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_ACTIVE, 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_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* HS : 11 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
|
||||
{{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 */
|
||||
{{BTA_DM_PM_SNIFF3, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
|
||||
{{BTA_DM_PM_SNIFF, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff */
|
||||
{{BTA_DM_PM_SNIFF, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_RETRY, 7000}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* AVK : 12 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF), /* allow sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF, 3000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
|
||||
{{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 */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF4, 3000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
}
|
||||
|
||||
#if BLE_INCLUDED == TRUE
|
||||
/* GATTC : 13 */
|
||||
, {
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 10000}, {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_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 10000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
#if defined(AMP_INCLUDED) && (AMP_INCLUDED == TRUE)
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* amp */
|
||||
#endif
|
||||
{{BTA_DM_PM_RETRY, 5000}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
}
|
||||
/* GATTS : 14 */
|
||||
, {
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_NO_PREF, 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_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
#if defined(AMP_INCLUDED) && (AMP_INCLUDED == TRUE)
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* amp */
|
||||
#endif
|
||||
{{BTA_DM_PM_RETRY, 5000}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BTE_SIM_APP /* For Insight builds only */
|
||||
/* Entries at the end of the pm_spec table are user-defined (runtime configurable),
|
||||
for power consumption experiments.
|
||||
Insight finds the first user-defined entry by looking for the first BTA_DM_PM_NO_PREF.
|
||||
The number of user_defined specs is defined by BTA_SWRAP_UD_PM_SPEC_COUNT */
|
||||
,
|
||||
{BTA_DM_PM_NO_PREF}, /* pm_spec USER_DEFINED_0 */
|
||||
{BTA_DM_PM_NO_PREF} /* pm_spec USER_DEFINED_1 */
|
||||
#endif /* BTE_SIM_APP */
|
||||
};
|
||||
|
||||
/* Please refer to the SNIFF table definitions in bta_api.h.
|
||||
*
|
||||
* Adding to or Modifying the Table
|
||||
* Additional sniff parameter entries can be added for BTA_DM_PM_SNIFF5 - BTA_DM_PM_SNIFF7.
|
||||
* Overrides of additional table entries can be specified in bdroid_buildcfg.h. If additional
|
||||
* sniff parameter entries are added or an override of an existing entry is specified in
|
||||
* bdroid_buildcfg.h then the BTA_DM_PM_*_IDX defines in bta_api.h will need to be match the new
|
||||
* ordering.
|
||||
*
|
||||
* Table Ordering
|
||||
* Sniff Table entries must be ordered from highest latency (biggest interval) to lowest latency.
|
||||
* If there is a conflict among the connected services the setting with the lowest latency will
|
||||
* be selected.
|
||||
*/
|
||||
tBTA_DM_PM_TYPE_QUALIFIER tBTM_PM_PWR_MD bta_dm_pm_md[] = {
|
||||
/*
|
||||
* More sniff parameter entries can be added for
|
||||
* BTA_DM_PM_SNIFF3 - BTA_DM_PM_SNIFF7, if needed. When entries are added or
|
||||
* removed, BTA_DM_PM_PARK_IDX needs to be updated to reflect the actual index
|
||||
* BTA_DM_PM_PARK_IDX is defined in bta_api.h and can be override by the
|
||||
* bdroid_buildcfg.h settings.
|
||||
* The SNIFF table entries must be in the order from highest latency (biggest
|
||||
* interval) to lowest latency. If there's a conflict among the connected
|
||||
* services, the setting with lowest latency wins.
|
||||
*/
|
||||
/* sniff modes: max interval, min interval, attempt, timeout */
|
||||
{BTA_DM_PM_SNIFF_MAX, BTA_DM_PM_SNIFF_MIN, BTA_DM_PM_SNIFF_ATTEMPT, BTA_DM_PM_SNIFF_TIMEOUT, BTM_PM_MD_SNIFF}, /* for BTA_DM_PM_SNIFF - A2DP */
|
||||
{BTA_DM_PM_SNIFF1_MAX, BTA_DM_PM_SNIFF1_MIN, BTA_DM_PM_SNIFF1_ATTEMPT, BTA_DM_PM_SNIFF1_TIMEOUT, BTM_PM_MD_SNIFF}, /* for BTA_DM_PM_SNIFF1 */
|
||||
{BTA_DM_PM_SNIFF2_MAX, BTA_DM_PM_SNIFF2_MIN, BTA_DM_PM_SNIFF2_ATTEMPT, BTA_DM_PM_SNIFF2_TIMEOUT, BTM_PM_MD_SNIFF}, /* for BTA_DM_PM_SNIFF2- HD idle */
|
||||
{BTA_DM_PM_SNIFF3_MAX, BTA_DM_PM_SNIFF3_MIN, BTA_DM_PM_SNIFF3_ATTEMPT, BTA_DM_PM_SNIFF3_TIMEOUT, BTM_PM_MD_SNIFF}, /* for BTA_DM_PM_SNIFF3- SCO open */
|
||||
{BTA_DM_PM_SNIFF4_MAX, BTA_DM_PM_SNIFF4_MIN, BTA_DM_PM_SNIFF4_ATTEMPT, BTA_DM_PM_SNIFF4_TIMEOUT, BTM_PM_MD_SNIFF}, /* for BTA_DM_PM_SNIFF4- HD active */
|
||||
{BTA_DM_PM_SNIFF5_MAX, BTA_DM_PM_SNIFF5_MIN, BTA_DM_PM_SNIFF5_ATTEMPT, BTA_DM_PM_SNIFF5_TIMEOUT, BTM_PM_MD_SNIFF}, /* for BTA_DM_PM_SNIFF5- HD active */
|
||||
{BTA_DM_PM_PARK_MAX, BTA_DM_PM_PARK_MIN, BTA_DM_PM_PARK_ATTEMPT, BTA_DM_PM_PARK_TIMEOUT, BTM_PM_MD_PARK}
|
||||
|
||||
#ifdef BTE_SIM_APP /* For Insight builds only */
|
||||
/* Entries at the end of the bta_dm_pm_md table are user-defined (runtime configurable),
|
||||
for power consumption experiments.
|
||||
Insight finds the first user-defined entry by looking for the first 'max=0'.
|
||||
The number of user_defined specs is defined by BTA_SWRAP_UD_PM_DM_COUNT */
|
||||
,
|
||||
{0}, /* CONN_OPEN/SCO_CLOSE power mode settings for pm_spec USER_DEFINED_0 */
|
||||
{0}, /* SCO_OPEN power mode settings for pm_spec USER_DEFINED_0 */
|
||||
|
||||
{0}, /* CONN_OPEN/SCO_CLOSE power mode settings for pm_spec USER_DEFINED_1 */
|
||||
{0} /* SCO_OPEN power mode settings for pm_spec USER_DEFINED_1 */
|
||||
#endif /* BTE_SIM_APP */
|
||||
};
|
||||
|
||||
/* 0=max_lat -> no SSR */
|
||||
/* the smaller of the SSR max latency wins.
|
||||
* the entries in this table must be from highest latency (biggest interval) to lowest latency */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
tBTA_DM_SSR_SPEC bta_dm_ssr_spec[] = {
|
||||
/*max_lat, min_rmt_to, min_loc_to*/
|
||||
{0, 0, 0}, /* BTA_DM_PM_SSR0 - do not use SSR */
|
||||
{0, 0, 2}, /* BTA_DM_PM_SSR1 - HH, can NOT share entry with any other profile,
|
||||
seting default max latency and min remote timeout as 0,
|
||||
and always read individual device preference from HH module */
|
||||
{1200, 2, 2}, /* BTA_DM_PM_SSR2 - others (as long as sniff is allowed)*/
|
||||
{360, 160, 2} /* BTA_DM_PM_SSR3 - HD */
|
||||
};
|
||||
|
||||
tBTA_DM_SSR_SPEC *p_bta_dm_ssr_spec = (tBTA_DM_SSR_SPEC *) &bta_dm_ssr_spec;
|
||||
#endif
|
||||
|
||||
tBTA_DM_PM_CFG *p_bta_dm_pm_cfg = (tBTA_DM_PM_CFG *) &bta_dm_pm_cfg;
|
||||
tBTA_DM_PM_SPEC *p_bta_dm_pm_spec = (tBTA_DM_PM_SPEC *) &bta_dm_pm_spec;
|
||||
tBTM_PM_PWR_MD *p_bta_dm_pm_md = (tBTM_PM_PWR_MD *) &bta_dm_pm_md;
|
||||
|
||||
/* The performance impact of EIR packet size
|
||||
**
|
||||
** When BTM_EIR_DEFAULT_FEC_REQUIRED is TRUE,
|
||||
** 1 to 17 bytes, DM1 is used and most robust.
|
||||
** 18 to 121 bytes, DM3 is used but impacts inquiry scan time with large number
|
||||
** of devices.(almost double with 150 users)
|
||||
** 122 to 224 bytes, DM5 is used but cause quite big performance loss even with
|
||||
** small number of users. so it is not recommended.
|
||||
** 225 to 240 bytes, DH5 is used without FEC but it not recommended.
|
||||
** (same reason of DM5)
|
||||
**
|
||||
** When BTM_EIR_DEFAULT_FEC_REQUIRED is FALSE,
|
||||
** 1 to 27 bytes, DH1 is used but only robust at short range.
|
||||
** 28 to 183 bytes, DH3 is used but only robust at short range and impacts inquiry
|
||||
** scan time with large number of devices.
|
||||
** 184 to 240 bytes, DH5 is used but it not recommended.
|
||||
*/
|
||||
|
||||
#if (BTA_EIR_CANNED_UUID_LIST == TRUE)
|
||||
/* for example */
|
||||
const UINT8 bta_dm_eir_uuid16_list[] = { 0x08, 0x11, /* Headset */
|
||||
0x1E, 0x11, /* Handsfree */
|
||||
0x0E, 0x11, /* AV Remote Control */
|
||||
0x0B, 0x11, /* Audio Sink */
|
||||
};
|
||||
#endif // BTA_EIR_CANNED_UUID_LIST
|
||||
|
||||
/* Extended Inquiry Response */
|
||||
const tBTA_DM_EIR_CONF bta_dm_eir_cfg = {
|
||||
50, /* minimum length of local name when it is shortened */
|
||||
/* if length of local name is longer than this and EIR has not enough */
|
||||
/* room for all UUID list then local name is shortened to this length */
|
||||
#if (BTA_EIR_CANNED_UUID_LIST == TRUE)
|
||||
8,
|
||||
(UINT8 *)bta_dm_eir_uuid16_list,
|
||||
#else // BTA_EIR_CANNED_UUID_LIST
|
||||
{ /* mask of UUID list in EIR */
|
||||
0xFFFFFFFF, /* LSB is the first UUID of the first 32 UUIDs in BTM_EIR_UUID_LKUP_TBL */
|
||||
0xFFFFFFFF /* LSB is the first UUID of the next 32 UUIDs in BTM_EIR_UUID_LKUP_TBL */
|
||||
/* BTM_EIR_UUID_LKUP_TBL can be overrided */
|
||||
},
|
||||
#endif // BTA_EIR_CANNED_UUID_LIST
|
||||
NULL, /* Inquiry TX power */
|
||||
0, /* length of flags in bytes */
|
||||
NULL, /* flags for EIR */
|
||||
0, /* length of manufacturer specific in bytes */
|
||||
NULL, /* manufacturer specific */
|
||||
0, /* length of additional data in bytes */
|
||||
NULL /* additional data */
|
||||
};
|
||||
tBTA_DM_EIR_CONF *p_bta_dm_eir_cfg = (tBTA_DM_EIR_CONF *) &bta_dm_eir_cfg;
|
||||
114
components/bt/bluedroid/bta/dm/bta_dm_ci.c
Normal file
114
components/bt/bluedroid/bta/dm/bta_dm_ci.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the API implementation file for the BTA device manager.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "gki.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_api.h"
|
||||
#include "bta_dm_int.h"
|
||||
#include <string.h>
|
||||
#include "bta_dm_ci.h"
|
||||
|
||||
|
||||
#if (BTM_OOB_INCLUDED == TRUE)
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_ci_io_req
|
||||
**
|
||||
** Description This function must be called in response to function
|
||||
** bta_dm_co_io_req(), if *p_oob_data to BTA_OOB_UNKNOWN
|
||||
** by bta_dm_co_io_req().
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_dm_ci_io_req(BD_ADDR bd_addr, tBTA_IO_CAP io_cap, tBTA_OOB_DATA oob_data,
|
||||
tBTA_AUTH_REQ auth_req)
|
||||
|
||||
{
|
||||
tBTA_DM_CI_IO_REQ *p_msg;
|
||||
|
||||
if ((p_msg = (tBTA_DM_CI_IO_REQ *) GKI_getbuf(sizeof(tBTA_DM_CI_IO_REQ))) != NULL) {
|
||||
p_msg->hdr.event = BTA_DM_CI_IO_REQ_EVT;
|
||||
bdcpy(p_msg->bd_addr, bd_addr);
|
||||
p_msg->io_cap = io_cap;
|
||||
p_msg->oob_data = oob_data;
|
||||
p_msg->auth_req = auth_req;
|
||||
bta_sys_sendmsg(p_msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_ci_rmt_oob
|
||||
**
|
||||
** Description This function must be called in response to function
|
||||
** bta_dm_co_rmt_oob() to provide the OOB data associated
|
||||
** with the remote device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_dm_ci_rmt_oob(BOOLEAN accept, BD_ADDR bd_addr, BT_OCTET16 c, BT_OCTET16 r)
|
||||
{
|
||||
tBTA_DM_CI_RMT_OOB *p_msg;
|
||||
|
||||
if ((p_msg = (tBTA_DM_CI_RMT_OOB *) GKI_getbuf(sizeof(tBTA_DM_CI_RMT_OOB))) != NULL) {
|
||||
p_msg->hdr.event = BTA_DM_CI_RMT_OOB_EVT;
|
||||
bdcpy(p_msg->bd_addr, bd_addr);
|
||||
p_msg->accept = accept;
|
||||
memcpy(p_msg->c, c, BT_OCTET16_LEN);
|
||||
memcpy(p_msg->r, r, BT_OCTET16_LEN);
|
||||
bta_sys_sendmsg(p_msg);
|
||||
}
|
||||
}
|
||||
#endif /* BTM_OOB_INCLUDED */
|
||||
|
||||
#if (BTM_SCO_HCI_INCLUDED == TRUE)
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sco_ci_data_ready
|
||||
**
|
||||
** Description This function sends an event to indicating that the phone
|
||||
** has SCO data ready.
|
||||
**
|
||||
** Parameters event: is obtained from bta_dm_sco_co_open() function, which
|
||||
** is the BTA event we want to send back to BTA module
|
||||
** when there is encoded data ready.
|
||||
** sco_handle: is the BTA sco handle which indicate a specific
|
||||
** SCO connection.
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_dm_sco_ci_data_ready(UINT16 event, UINT16 sco_handle)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = event;
|
||||
p_buf->layer_specific = sco_handle;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
1181
components/bt/bluedroid/bta/dm/bta_dm_int.h
Normal file
1181
components/bt/bluedroid/bta/dm/bta_dm_int.h
Normal file
File diff suppressed because it is too large
Load Diff
378
components/bt/bluedroid/bta/dm/bta_dm_main.c
Normal file
378
components/bt/bluedroid/bta/dm/bta_dm_main.c
Normal file
@@ -0,0 +1,378 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the main implementation file for the BTA device manager.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bta_api.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_dm_int.h"
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and types
|
||||
*****************************************************************************/
|
||||
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
tBTA_DM_CB bta_dm_cb;
|
||||
tBTA_DM_SEARCH_CB bta_dm_search_cb;
|
||||
tBTA_DM_DI_CB bta_dm_di_cb;
|
||||
#endif
|
||||
|
||||
|
||||
#define BTA_DM_NUM_ACTIONS (BTA_DM_MAX_EVT & 0x00ff)
|
||||
|
||||
/* type for action functions */
|
||||
typedef void (*tBTA_DM_ACTION)(tBTA_DM_MSG *p_data);
|
||||
|
||||
/* action function list */
|
||||
const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
|
||||
|
||||
/* device manager local device API events */
|
||||
bta_dm_enable, /* 0 BTA_DM_API_ENABLE_EVT */
|
||||
bta_dm_disable, /* 1 BTA_DM_API_DISABLE_EVT */
|
||||
bta_dm_set_dev_name, /* 2 BTA_DM_API_SET_NAME_EVT */
|
||||
bta_dm_set_visibility, /* 3 BTA_DM_API_SET_VISIBILITY_EVT */
|
||||
bta_dm_acl_change, /* 8 BTA_DM_ACL_CHANGE_EVT */
|
||||
bta_dm_add_device, /* 9 BTA_DM_API_ADD_DEVICE_EVT */
|
||||
bta_dm_close_acl, /* 10 BTA_DM_API_ADD_DEVICE_EVT */
|
||||
|
||||
/* security API events */
|
||||
bta_dm_bond, /* 11 BTA_DM_API_BOND_EVT */
|
||||
bta_dm_bond_cancel, /* 12 BTA_DM_API_BOND_CANCEL_EVT */
|
||||
bta_dm_pin_reply, /* 13 BTA_DM_API_PIN_REPLY_EVT */
|
||||
|
||||
/* power manger events */
|
||||
bta_dm_pm_btm_status, /* 16 BTA_DM_PM_BTM_STATUS_EVT */
|
||||
bta_dm_pm_timer, /* 17 BTA_DM_PM_TIMER_EVT*/
|
||||
|
||||
/* simple pairing events */
|
||||
bta_dm_confirm, /* 18 BTA_DM_API_CONFIRM_EVT */
|
||||
|
||||
bta_dm_set_encryption, /* BTA_DM_API_SET_ENCRYPTION_EVT */
|
||||
|
||||
#if (BTM_OOB_INCLUDED == TRUE)
|
||||
bta_dm_loc_oob, /* 20 BTA_DM_API_LOC_OOB_EVT */
|
||||
bta_dm_ci_io_req_act, /* 21 BTA_DM_CI_IO_REQ_EVT */
|
||||
bta_dm_ci_rmt_oob_act, /* 22 BTA_DM_CI_RMT_OOB_EVT */
|
||||
#endif /* BTM_OOB_INCLUDED */
|
||||
|
||||
|
||||
#if BLE_INCLUDED == TRUE
|
||||
bta_dm_add_blekey, /* BTA_DM_API_ADD_BLEKEY_EVT */
|
||||
bta_dm_add_ble_device, /* BTA_DM_API_ADD_BLEDEVICE_EVT */
|
||||
bta_dm_ble_passkey_reply, /* BTA_DM_API_BLE_PASSKEY_REPLY_EVT */
|
||||
bta_dm_ble_confirm_reply, /* BTA_DM_API_BLE_CONFIRM_REPLY_EVT */
|
||||
bta_dm_security_grant,
|
||||
bta_dm_ble_set_bg_conn_type,
|
||||
bta_dm_ble_set_conn_params, /* BTA_DM_API_BLE_CONN_PARAM_EVT */
|
||||
bta_dm_ble_set_conn_scan_params, /* BTA_DM_API_BLE_CONN_SCAN_PARAM_EVT */
|
||||
bta_dm_ble_set_scan_params, /* BTA_DM_API_BLE_SCAN_PARAM_EVT */
|
||||
bta_dm_ble_set_scan_fil_params, /* BTA_DM_API_BLE_SCAN_FIL_PARAM_EVT */
|
||||
bta_dm_ble_observe, /* BTA_DM_API_BLE_OBSERVE_EVT*/
|
||||
bta_dm_ble_update_conn_params, /* BTA_DM_API_UPDATE_CONN_PARAM_EVT */
|
||||
/* This handler function added by
|
||||
Yulong at 2016/9/9 to support the
|
||||
random address setting for the APP */
|
||||
bta_dm_ble_set_rand_address, /* BTA_DM_API_SET_RAND_ADDR_EVT*/
|
||||
/* This handler function added by
|
||||
Yulong at 2016/10/19 to support
|
||||
stop the ble advertising setting
|
||||
by the APP */
|
||||
bta_dm_ble_stop_advertising, /* BTA_DM_API_BLE_STOP_ADV_EVT*/
|
||||
#if BLE_PRIVACY_SPT == TRUE
|
||||
bta_dm_ble_config_local_privacy, /* BTA_DM_API_LOCAL_PRIVACY_EVT */
|
||||
#endif
|
||||
bta_dm_ble_set_adv_params, /* BTA_DM_API_BLE_ADV_PARAM_EVT */
|
||||
bta_dm_ble_set_adv_params_all, /* BTA_DM_API_BLE_ADV_PARAM_All_EVT */
|
||||
bta_dm_ble_set_adv_config, /* BTA_DM_API_BLE_SET_ADV_CONFIG_EVT */
|
||||
/* New function to allow set raw adv
|
||||
data to HCI */
|
||||
bta_dm_ble_set_adv_config_raw, /* BTA_DM_API_BLE_SET_ADV_CONFIG_RAW_EVT */
|
||||
bta_dm_ble_set_scan_rsp, /* BTA_DM_API_BLE_SET_SCAN_RSP_EVT */
|
||||
/* New function to allow set raw scan
|
||||
response data to HCI */
|
||||
bta_dm_ble_set_scan_rsp_raw, /* BTA_DM_API_BLE_SET_SCAN_RSP_RAW_EVT */
|
||||
bta_dm_ble_broadcast, /* BTA_DM_API_BLE_BROADCAST_EVT */
|
||||
bta_dm_ble_set_data_length, /* BTA_DM_API_SET_DATA_LENGTH_EVT */
|
||||
#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
|
||||
bta_dm_cfg_filter_cond, /* BTA_DM_API_CFG_FILTER_COND_EVT */
|
||||
bta_dm_scan_filter_param_setup, /* BTA_DM_API_SCAN_FILTER_SETUP_EVT */
|
||||
bta_dm_enable_scan_filter, /* BTA_DM_API_SCAN_FILTER_ENABLE_EVT */
|
||||
#endif
|
||||
bta_dm_ble_multi_adv_enb, /* BTA_DM_API_BLE_MULTI_ADV_ENB_EVT*/
|
||||
bta_dm_ble_multi_adv_upd_param, /* BTA_DM_API_BLE_MULTI_ADV_PARAM_UPD_EVT */
|
||||
bta_dm_ble_multi_adv_data, /* BTA_DM_API_BLE_MULTI_ADV_DATA_EVT */
|
||||
btm_dm_ble_multi_adv_disable, /* BTA_DM_API_BLE_MULTI_ADV_DISABLE_EVT */
|
||||
bta_dm_ble_setup_storage, /* BTA_DM_API_BLE_SETUP_STORAGE_EVT */
|
||||
bta_dm_ble_enable_batch_scan, /* BTA_DM_API_BLE_ENABLE_BATCH_SCAN_EVT */
|
||||
bta_dm_ble_disable_batch_scan, /* BTA_DM_API_BLE_DISABLE_BATCH_SCAN_EVT */
|
||||
bta_dm_ble_read_scan_reports, /* BTA_DM_API_BLE_READ_SCAN_REPORTS_EVT */
|
||||
bta_dm_ble_track_advertiser, /* BTA_DM_API_BLE_TRACK_ADVERTISER_EVT */
|
||||
bta_dm_ble_get_energy_info, /* BTA_DM_API_BLE_ENERGY_INFO_EVT */
|
||||
#endif
|
||||
|
||||
bta_dm_enable_test_mode, /* BTA_DM_API_ENABLE_TEST_MODE_EVT */
|
||||
bta_dm_disable_test_mode, /* BTA_DM_API_DISABLE_TEST_MODE_EVT */
|
||||
bta_dm_execute_callback, /* BTA_DM_API_EXECUTE_CBACK_EVT */
|
||||
|
||||
bta_dm_remove_all_acl, /* BTA_DM_API_REMOVE_ALL_ACL_EVT */
|
||||
bta_dm_remove_device, /* BTA_DM_API_REMOVE_DEVICE_EVT */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* state machine action enumeration list */
|
||||
enum {
|
||||
BTA_DM_API_SEARCH, /* 0 bta_dm_search_start */
|
||||
BTA_DM_API_SEARCH_CANCEL, /* 1 bta_dm_search_cancel */
|
||||
BTA_DM_API_DISCOVER, /* 2 bta_dm_discover */
|
||||
BTA_DM_INQUIRY_CMPL, /* 3 bta_dm_inq_cmpl */
|
||||
BTA_DM_REMT_NAME, /* 4 bta_dm_rmt_name */
|
||||
BTA_DM_SDP_RESULT, /* 5 bta_dm_sdp_result */
|
||||
BTA_DM_SEARCH_CMPL, /* 6 bta_dm_search_cmpl*/
|
||||
BTA_DM_FREE_SDP_DB, /* 7 bta_dm_free_sdp_db */
|
||||
BTA_DM_DISC_RESULT, /* 8 bta_dm_disc_result */
|
||||
BTA_DM_SEARCH_RESULT, /* 9 bta_dm_search_result */
|
||||
BTA_DM_QUEUE_SEARCH, /* 10 bta_dm_queue_search */
|
||||
BTA_DM_QUEUE_DISC, /* 11 bta_dm_queue_disc */
|
||||
BTA_DM_SEARCH_CLEAR_QUEUE, /* 12 bta_dm_search_clear_queue */
|
||||
BTA_DM_SEARCH_CANCEL_CMPL, /* 13 bta_dm_search_cancel_cmpl */
|
||||
BTA_DM_SEARCH_CANCEL_NOTIFY, /* 14 bta_dm_search_cancel_notify */
|
||||
BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL, /* 15 bta_dm_search_cancel_transac_cmpl */
|
||||
BTA_DM_DISC_RMT_NAME, /* 16 bta_dm_disc_rmt_name */
|
||||
BTA_DM_API_DI_DISCOVER, /* 17 bta_dm_di_disc */
|
||||
#if BLE_INCLUDED == TRUE
|
||||
BTA_DM_CLOSE_GATT_CONN, /* 18 bta_dm_close_gatt_conn */
|
||||
#endif
|
||||
BTA_DM_SEARCH_NUM_ACTIONS /* 19 */
|
||||
};
|
||||
|
||||
|
||||
/* action function list */
|
||||
const tBTA_DM_ACTION bta_dm_search_action[] = {
|
||||
|
||||
bta_dm_search_start, /* 0 BTA_DM_API_SEARCH */
|
||||
bta_dm_search_cancel, /* 1 BTA_DM_API_SEARCH_CANCEL */
|
||||
bta_dm_discover, /* 2 BTA_DM_API_DISCOVER */
|
||||
bta_dm_inq_cmpl, /* 3 BTA_DM_INQUIRY_CMPL */
|
||||
bta_dm_rmt_name, /* 4 BTA_DM_REMT_NAME */
|
||||
bta_dm_sdp_result, /* 5 BTA_DM_SDP_RESULT */
|
||||
bta_dm_search_cmpl, /* 6 BTA_DM_SEARCH_CMPL */
|
||||
bta_dm_free_sdp_db, /* 7 BTA_DM_FREE_SDP_DB */
|
||||
bta_dm_disc_result, /* 8 BTA_DM_DISC_RESULT */
|
||||
bta_dm_search_result, /* 9 BTA_DM_SEARCH_RESULT */
|
||||
bta_dm_queue_search, /* 10 BTA_DM_QUEUE_SEARCH */
|
||||
bta_dm_queue_disc, /* 11 BTA_DM_QUEUE_DISC */
|
||||
bta_dm_search_clear_queue, /* 12 BTA_DM_SEARCH_CLEAR_QUEUE */
|
||||
bta_dm_search_cancel_cmpl, /* 13 BTA_DM_SEARCH_CANCEL_CMPL */
|
||||
bta_dm_search_cancel_notify, /* 14 BTA_DM_SEARCH_CANCEL_NOTIFY */
|
||||
bta_dm_search_cancel_transac_cmpl, /* 15 BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL */
|
||||
bta_dm_disc_rmt_name, /* 16 BTA_DM_DISC_RMT_NAME */
|
||||
bta_dm_di_disc /* 17 BTA_DM_API_DI_DISCOVER */
|
||||
#if BLE_INCLUDED == TRUE
|
||||
, bta_dm_close_gatt_conn
|
||||
#endif
|
||||
};
|
||||
|
||||
#define BTA_DM_SEARCH_IGNORE BTA_DM_SEARCH_NUM_ACTIONS
|
||||
/* state table information */
|
||||
#define BTA_DM_SEARCH_ACTIONS 2 /* number of actions */
|
||||
#define BTA_DM_SEARCH_NEXT_STATE 2 /* position of next state */
|
||||
#define BTA_DM_SEARCH_NUM_COLS 3 /* number of columns in state tables */
|
||||
|
||||
|
||||
|
||||
/* state table for listen state */
|
||||
const UINT8 bta_dm_search_idle_st_table[][BTA_DM_SEARCH_NUM_COLS] = {
|
||||
|
||||
/* Event Action 1 Action 2 Next State */
|
||||
/* API_SEARCH */ {BTA_DM_API_SEARCH, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE},
|
||||
/* API_SEARCH_CANCEL */ {BTA_DM_SEARCH_CANCEL_NOTIFY, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
/* API_SEARCH_DISC */ {BTA_DM_API_DISCOVER, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE},
|
||||
/* INQUIRY_CMPL */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
/* REMT_NAME_EVT */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
/* SDP_RESULT_EVT */ {BTA_DM_FREE_SDP_DB, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
/* SEARCH_CMPL_EVT */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
/* DISCV_RES_EVT */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
/* API_DI_DISCOVER_EVT */ {BTA_DM_API_DI_DISCOVER, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE}
|
||||
#if BLE_INCLUDED == TRUE
|
||||
/* DISC_CLOSE_TOUT_EVT */ , {BTA_DM_CLOSE_GATT_CONN, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE}
|
||||
#endif
|
||||
};
|
||||
const UINT8 bta_dm_search_search_active_st_table[][BTA_DM_SEARCH_NUM_COLS] = {
|
||||
|
||||
/* Event Action 1 Action 2 Next State */
|
||||
/* API_SEARCH */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE},
|
||||
/* API_SEARCH_CANCEL */ {BTA_DM_API_SEARCH_CANCEL, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_CANCELLING},
|
||||
/* API_SEARCH_DISC */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE},
|
||||
/* INQUIRY_CMPL */ {BTA_DM_INQUIRY_CMPL, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE},
|
||||
/* REMT_NAME_EVT */ {BTA_DM_REMT_NAME, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE},
|
||||
/* SDP_RESULT_EVT */ {BTA_DM_SDP_RESULT, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE},
|
||||
/* SEARCH_CMPL_EVT */ {BTA_DM_SEARCH_CMPL, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
/* DISCV_RES_EVT */ {BTA_DM_SEARCH_RESULT, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE},
|
||||
/* API_DI_DISCOVER_EVT */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE}
|
||||
#if BLE_INCLUDED == TRUE
|
||||
/* DISC_CLOSE_TOUT_EVT */ , {BTA_DM_CLOSE_GATT_CONN, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
const UINT8 bta_dm_search_search_cancelling_st_table[][BTA_DM_SEARCH_NUM_COLS] = {
|
||||
|
||||
/* Event Action 1 Action 2 Next State */
|
||||
/* API_SEARCH */ {BTA_DM_QUEUE_SEARCH, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_CANCELLING},
|
||||
/* API_SEARCH_CANCEL */ {BTA_DM_SEARCH_CLEAR_QUEUE, BTA_DM_SEARCH_CANCEL_NOTIFY, BTA_DM_SEARCH_CANCELLING},
|
||||
/* API_SEARCH_DISC */ {BTA_DM_QUEUE_DISC, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_CANCELLING},
|
||||
/* INQUIRY_CMPL */ {BTA_DM_SEARCH_CANCEL_CMPL, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
/* REMT_NAME_EVT */ {BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL, BTA_DM_SEARCH_CANCEL_CMPL, BTA_DM_SEARCH_IDLE},
|
||||
/* SDP_RESULT_EVT */ {BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL, BTA_DM_SEARCH_CANCEL_CMPL, BTA_DM_SEARCH_IDLE},
|
||||
/* SEARCH_CMPL_EVT */ {BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL, BTA_DM_SEARCH_CANCEL_CMPL, BTA_DM_SEARCH_IDLE},
|
||||
/* DISCV_RES_EVT */ {BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL, BTA_DM_SEARCH_CANCEL_CMPL, BTA_DM_SEARCH_IDLE},
|
||||
/* API_DI_DISCOVER_EVT */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_CANCELLING}
|
||||
#if BLE_INCLUDED == TRUE
|
||||
/* DISC_CLOSE_TOUT_EVT */ , {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_CANCELLING}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
const UINT8 bta_dm_search_disc_active_st_table[][BTA_DM_SEARCH_NUM_COLS] = {
|
||||
|
||||
/* Event Action 1 Action 2 Next State */
|
||||
/* API_SEARCH */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE},
|
||||
/* API_SEARCH_CANCEL */ {BTA_DM_SEARCH_CANCEL_NOTIFY, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_CANCELLING},
|
||||
/* API_SEARCH_DISC */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE},
|
||||
/* INQUIRY_CMPL */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE},
|
||||
/* REMT_NAME_EVT */ {BTA_DM_DISC_RMT_NAME, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE},
|
||||
/* SDP_RESULT_EVT */ {BTA_DM_SDP_RESULT, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE},
|
||||
/* SEARCH_CMPL_EVT */ {BTA_DM_SEARCH_CMPL, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
/* DISCV_RES_EVT */ {BTA_DM_DISC_RESULT, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE},
|
||||
/* API_DI_DISCOVER_EVT */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE}
|
||||
|
||||
#if BLE_INCLUDED == TRUE
|
||||
/* DISC_CLOSE_TOUT_EVT */ , {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE}
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef const UINT8 (*tBTA_DM_ST_TBL)[BTA_DM_SEARCH_NUM_COLS];
|
||||
|
||||
/* state table */
|
||||
const tBTA_DM_ST_TBL bta_dm_search_st_tbl[] = {
|
||||
bta_dm_search_idle_st_table,
|
||||
bta_dm_search_search_active_st_table,
|
||||
bta_dm_search_search_cancelling_st_table,
|
||||
bta_dm_search_disc_active_st_table
|
||||
};
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sm_disable
|
||||
**
|
||||
** Description unregister BTA DM
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_dm_sm_disable( )
|
||||
{
|
||||
bta_sys_deregister( BTA_ID_DM );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sm_execute
|
||||
**
|
||||
** Description State machine event handling function for DM
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_dm_sm_execute(BT_HDR *p_msg)
|
||||
{
|
||||
UINT16 event = p_msg->event & 0x00ff;
|
||||
|
||||
APPL_TRACE_EVENT("bta_dm_sm_execute event:0x%x", event);
|
||||
|
||||
/* execute action functions */
|
||||
if (event < BTA_DM_NUM_ACTIONS) {
|
||||
(*bta_dm_action[event])( (tBTA_DM_MSG *) p_msg);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sm_search_disable
|
||||
**
|
||||
** Description unregister BTA SEARCH DM
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_dm_search_sm_disable( )
|
||||
{
|
||||
bta_sys_deregister( BTA_ID_DM_SEARCH );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_search_sm_execute
|
||||
**
|
||||
** Description State machine event handling function for DM
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_dm_search_sm_execute(BT_HDR *p_msg)
|
||||
{
|
||||
tBTA_DM_ST_TBL state_table;
|
||||
UINT8 action;
|
||||
int i;
|
||||
|
||||
APPL_TRACE_EVENT("bta_dm_search_sm_execute state:%d, event:0x%x",
|
||||
bta_dm_search_cb.state, p_msg->event);
|
||||
|
||||
/* look up the state table for the current state */
|
||||
state_table = bta_dm_search_st_tbl[bta_dm_search_cb.state];
|
||||
|
||||
bta_dm_search_cb.state = state_table[p_msg->event & 0x00ff][BTA_DM_SEARCH_NEXT_STATE];
|
||||
|
||||
|
||||
/* execute action functions */
|
||||
for (i = 0; i < BTA_DM_SEARCH_ACTIONS; i++) {
|
||||
if ((action = state_table[p_msg->event & 0x00ff][i]) != BTA_DM_SEARCH_IGNORE) {
|
||||
(*bta_dm_search_action[action])( (tBTA_DM_MSG *) p_msg);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
1158
components/bt/bluedroid/bta/dm/bta_dm_pm.c
Normal file
1158
components/bt/bluedroid/bta/dm/bta_dm_pm.c
Normal file
File diff suppressed because it is too large
Load Diff
655
components/bt/bluedroid/bta/dm/bta_dm_sco.c
Normal file
655
components/bt/bluedroid/bta/dm/bta_dm_sco.c
Normal file
@@ -0,0 +1,655 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the down sampling utility to convert PCM samples in
|
||||
* 16k/32k/48k/44.1k/22050/11025 sampling rate into 8K/16bits samples
|
||||
* required for SCO channel format. One API function isprovided and only
|
||||
* possible to be used when transmitting SCO data is sent via HCI
|
||||
* interface.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include <string.h>
|
||||
#include "bta_api.h"
|
||||
#include "bta_sys.h"
|
||||
|
||||
#if (BTM_SCO_HCI_INCLUDED == TRUE)
|
||||
|
||||
#ifndef BTA_DM_SCO_DEBUG
|
||||
#define BTA_DM_SCO_DEBUG FALSE
|
||||
#endif
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
|
||||
#define BTA_DM_PCM_OVERLAP_SIZE 48
|
||||
|
||||
#define BTA_DM_PCM_SMPL_RATE_44100 44100
|
||||
#define BTA_DM_PCM_SMPL_RATE_22050 22050
|
||||
#define BTA_DM_PCM_SMPL_RATE_11025 11025
|
||||
|
||||
/*****************************************************************************
|
||||
** Data types for PCM Resampling utility
|
||||
*****************************************************************************/
|
||||
|
||||
typedef INT32 (*PCONVERT_TO_BT_FILTERED) (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
|
||||
UINT32 dwSrcSps, INT32 *pLastCurPos, UINT8 *pOverlapArea);
|
||||
typedef INT32 (*PCONVERT_TO_BT_NOFILTER) (void *pSrc, void *pDst, UINT32 dwSrcSamples,
|
||||
UINT32 dwSrcSps);
|
||||
typedef struct {
|
||||
UINT8 overlap_area[BTA_DM_PCM_OVERLAP_SIZE * 4];
|
||||
UINT32 cur_pos; /* current position */
|
||||
UINT32 src_sps; /* samples per second (source audio data) */
|
||||
PCONVERT_TO_BT_FILTERED filter; /* the action function to do the
|
||||
conversion 44100, 22050, 11025*/
|
||||
PCONVERT_TO_BT_NOFILTER nofilter; /* the action function to do
|
||||
the conversion 48000, 32000, 16000*/
|
||||
UINT32 bits; /* number of bits per pcm sample */
|
||||
UINT32 n_channels; /* number of channels (i.e. mono(1), stereo(2)...) */
|
||||
UINT32 sample_size;
|
||||
UINT32 can_be_filtered;
|
||||
UINT32 divisor;
|
||||
} tBTA_DM_PCM_RESAMPLE_CB;
|
||||
|
||||
tBTA_DM_PCM_RESAMPLE_CB bta_dm_pcm_cb;
|
||||
|
||||
/*****************************************************************************
|
||||
** Macro Definition
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#define CHECK_SATURATION16(x) \
|
||||
if (x > 32767) \
|
||||
x = 32767; \
|
||||
else if (x < -32768) \
|
||||
x = -32768;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
#define CONVERT_44100_TO_BLUETOOTH(pStart, pEnd) \
|
||||
{ \
|
||||
INT32 out1, out2, out3, out4, out5; \
|
||||
SRC_TYPE *pS = (SRC_TYPE *)pStart; \
|
||||
SRC_TYPE *pSEnd = (SRC_TYPE *)pEnd; \
|
||||
\
|
||||
while (pS < pSEnd) \
|
||||
{ \
|
||||
CurrentPos -= 8000; \
|
||||
\
|
||||
if (CurrentPos >= 0) \
|
||||
{ \
|
||||
pS += SRC_CHANNELS; \
|
||||
continue; \
|
||||
} \
|
||||
CurrentPos += dwSrcSps; \
|
||||
\
|
||||
out1 = (SRC_SAMPLE(0) * 1587) \
|
||||
+ ((SRC_SAMPLE(1) + SRC_SAMPLE(-1)) * 1522) \
|
||||
+ ((SRC_SAMPLE(2) + SRC_SAMPLE(-2)) * 1337) \
|
||||
+ ((SRC_SAMPLE(3) + SRC_SAMPLE(-3)) * 1058); \
|
||||
\
|
||||
out1 = out1 / 30000; \
|
||||
\
|
||||
out2 = ((SRC_SAMPLE(4) + SRC_SAMPLE(-4)) * 725) \
|
||||
+ ((SRC_SAMPLE(5) + SRC_SAMPLE(-5)) * 384) \
|
||||
+ ((SRC_SAMPLE(6) + SRC_SAMPLE(-6)) * 79); \
|
||||
\
|
||||
out2 = out2 / 30000; \
|
||||
\
|
||||
out3 = ((SRC_SAMPLE(7) + SRC_SAMPLE(-7)) * 156) \
|
||||
+ ((SRC_SAMPLE(8) + SRC_SAMPLE(-8)) * 298) \
|
||||
+ ((SRC_SAMPLE(9) + SRC_SAMPLE(-9)) * 345); \
|
||||
\
|
||||
out3 = out3 / 30000; \
|
||||
\
|
||||
out4 = ((SRC_SAMPLE(10) + SRC_SAMPLE(-10)) * 306) \
|
||||
+ ((SRC_SAMPLE(11) + SRC_SAMPLE(-11)) * 207) \
|
||||
+ ((SRC_SAMPLE(12) + SRC_SAMPLE(-12)) * 78); \
|
||||
\
|
||||
out4 = out4 / 30000; \
|
||||
\
|
||||
out5 = out1 + out2 - out3 - out4; \
|
||||
\
|
||||
CHECK_SATURATION16(out5); \
|
||||
*psBtOut++ = (INT16)out5; \
|
||||
\
|
||||
pS += SRC_CHANNELS; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
#define CONVERT_22050_TO_BLUETOOTH(pStart, pEnd) \
|
||||
{ \
|
||||
INT32 out1, out2, out3, out4, out5; \
|
||||
SRC_TYPE *pS = (SRC_TYPE *)pStart; \
|
||||
SRC_TYPE *pSEnd = (SRC_TYPE *)pEnd; \
|
||||
\
|
||||
while (pS < pSEnd) \
|
||||
{ \
|
||||
CurrentPos -= 8000; \
|
||||
\
|
||||
if (CurrentPos >= 0) \
|
||||
{ \
|
||||
pS += SRC_CHANNELS; \
|
||||
continue; \
|
||||
} \
|
||||
CurrentPos += dwSrcSps; \
|
||||
\
|
||||
out1 = (SRC_SAMPLE(0) * 2993) \
|
||||
+ ((SRC_SAMPLE(1) + SRC_SAMPLE(-1)) * 2568) \
|
||||
+ ((SRC_SAMPLE(2) + SRC_SAMPLE(-2)) * 1509) \
|
||||
+ ((SRC_SAMPLE(3) + SRC_SAMPLE(-3)) * 331); \
|
||||
\
|
||||
out1 = out1 / 30000; \
|
||||
\
|
||||
out2 = ((SRC_SAMPLE(4) + SRC_SAMPLE(-4)) * 454) \
|
||||
+ ((SRC_SAMPLE(5) + SRC_SAMPLE(-5)) * 620) \
|
||||
+ ((SRC_SAMPLE(6) + SRC_SAMPLE(-6)) * 305); \
|
||||
\
|
||||
out2 = out2 / 30000; \
|
||||
\
|
||||
out3 = ((SRC_SAMPLE(7) + SRC_SAMPLE(-7)) * 127) \
|
||||
+ ((SRC_SAMPLE(8) + SRC_SAMPLE(-8)) * 350) \
|
||||
+ ((SRC_SAMPLE(9) + SRC_SAMPLE(-9)) * 265) \
|
||||
+ ((SRC_SAMPLE(10) + SRC_SAMPLE(-10)) * 6); \
|
||||
\
|
||||
out3 = out3 / 30000; \
|
||||
\
|
||||
out4 = ((SRC_SAMPLE(11) + SRC_SAMPLE(-11)) * 201); \
|
||||
\
|
||||
out4 = out4 / 30000; \
|
||||
\
|
||||
out5 = out1 - out2 + out3 - out4; \
|
||||
\
|
||||
CHECK_SATURATION16(out5); \
|
||||
*psBtOut++ = (INT16)out5; \
|
||||
\
|
||||
pS += SRC_CHANNELS; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
#define CONVERT_11025_TO_BLUETOOTH(pStart, pEnd) \
|
||||
{ \
|
||||
INT32 out1; \
|
||||
SRC_TYPE *pS = (SRC_TYPE *)pStart; \
|
||||
SRC_TYPE *pSEnd = (SRC_TYPE *)pEnd; \
|
||||
\
|
||||
while (pS < pSEnd) \
|
||||
{ \
|
||||
CurrentPos -= 8000; \
|
||||
\
|
||||
if (CurrentPos >= 0) \
|
||||
{ \
|
||||
pS += SRC_CHANNELS; \
|
||||
continue; \
|
||||
} \
|
||||
CurrentPos += dwSrcSps; \
|
||||
\
|
||||
out1 = (SRC_SAMPLE(0) * 6349) \
|
||||
+ ((SRC_SAMPLE(1) + SRC_SAMPLE(-1)) * 2874) \
|
||||
- ((SRC_SAMPLE(2) + SRC_SAMPLE(-2)) * 1148) \
|
||||
- ((SRC_SAMPLE(3) + SRC_SAMPLE(-3)) * 287) \
|
||||
+ ((SRC_SAMPLE(4) + SRC_SAMPLE(-4)) * 675) \
|
||||
- ((SRC_SAMPLE(5) + SRC_SAMPLE(-5)) * 258) \
|
||||
- ((SRC_SAMPLE(6) + SRC_SAMPLE(-6)) * 206) \
|
||||
+ ((SRC_SAMPLE(7) + SRC_SAMPLE(-7)) * 266); \
|
||||
\
|
||||
out1 = out1 / 30000; \
|
||||
\
|
||||
CHECK_SATURATION16(out1); \
|
||||
*psBtOut++ = (INT16)out1; \
|
||||
\
|
||||
pS += SRC_CHANNELS; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
#undef SRC_CHANNELS
|
||||
#undef SRC_SAMPLE
|
||||
#undef SRC_TYPE
|
||||
|
||||
#define SRC_TYPE UINT8
|
||||
#define SRC_CHANNELS 1
|
||||
#define SRC_SAMPLE(x) ((pS[x] - 0x80) << 8)
|
||||
|
||||
/*****************************************************************************
|
||||
** Local Function
|
||||
*****************************************************************************/
|
||||
INT32 Convert_8M_ToBT_Filtered (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
|
||||
UINT32 dwSrcSps, INT32 *pLastCurPos, UINT8 *pOverlapArea)
|
||||
{
|
||||
INT32 CurrentPos = *pLastCurPos;
|
||||
SRC_TYPE *pIn, *pInEnd;
|
||||
SRC_TYPE *pOv, *pOvEnd;
|
||||
INT16 *psBtOut = (INT16 *)pDst;
|
||||
#if BTA_DM_SCO_DEBUG
|
||||
APPL_TRACE_DEBUG("Convert_8M_ToBT_Filtered, CurrentPos %d\n", CurrentPos);
|
||||
#endif
|
||||
memcpy (pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 2), pSrc, BTA_DM_PCM_OVERLAP_SIZE * 2);
|
||||
|
||||
pOv = (SRC_TYPE *)(pOverlapArea + BTA_DM_PCM_OVERLAP_SIZE);
|
||||
pOvEnd = (SRC_TYPE *)(pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 3));
|
||||
|
||||
pIn = (SRC_TYPE *)(pSrc + BTA_DM_PCM_OVERLAP_SIZE);
|
||||
pInEnd = (SRC_TYPE *)(pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - \
|
||||
BTA_DM_PCM_OVERLAP_SIZE);
|
||||
|
||||
if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_44100) {
|
||||
CONVERT_44100_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_44100_TO_BLUETOOTH(pIn, pInEnd);
|
||||
} else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_22050) {
|
||||
CONVERT_22050_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_22050_TO_BLUETOOTH(pIn, pInEnd);
|
||||
} else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_11025) {
|
||||
CONVERT_11025_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_11025_TO_BLUETOOTH(pIn, pInEnd);
|
||||
}
|
||||
|
||||
memcpy (pOverlapArea, pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - \
|
||||
(BTA_DM_PCM_OVERLAP_SIZE * 2), BTA_DM_PCM_OVERLAP_SIZE * 2);
|
||||
|
||||
*pLastCurPos = CurrentPos;
|
||||
|
||||
return (psBtOut - (INT16 *)pDst);
|
||||
}
|
||||
|
||||
INT32 Convert_8M_ToBT_NoFilter (void *pSrc, void *pDst, UINT32 dwSrcSamples, UINT32 dwSrcSps)
|
||||
{
|
||||
INT32 CurrentPos;
|
||||
UINT8 *pbSrc = (UINT8 *)pSrc;
|
||||
INT16 *psDst = (INT16 *)pDst;
|
||||
INT16 sWorker;
|
||||
|
||||
// start at dwSpsSrc / 2, decrement by 8000
|
||||
//
|
||||
CurrentPos = (dwSrcSps >> 1);
|
||||
|
||||
while (dwSrcSamples--) {
|
||||
CurrentPos -= 8000;
|
||||
|
||||
if (CurrentPos >= 0) {
|
||||
pbSrc++;
|
||||
} else {
|
||||
sWorker = *pbSrc++;
|
||||
sWorker -= 0x80;
|
||||
sWorker <<= 8;
|
||||
|
||||
*psDst++ = sWorker;
|
||||
|
||||
CurrentPos += dwSrcSps;
|
||||
}
|
||||
}
|
||||
|
||||
return (psDst - (INT16 *)pDst);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
#undef SRC_CHANNELS
|
||||
#undef SRC_SAMPLE
|
||||
#undef SRC_TYPE
|
||||
|
||||
#define SRC_TYPE INT16
|
||||
#define SRC_CHANNELS 1
|
||||
#define SRC_SAMPLE(x) pS[x]
|
||||
|
||||
INT32 Convert_16M_ToBT_Filtered (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
|
||||
UINT32 dwSrcSps, INT32 *pLastCurPos, UINT8 *pOverlapArea)
|
||||
{
|
||||
INT32 CurrentPos = *pLastCurPos;
|
||||
SRC_TYPE *pIn, *pInEnd;
|
||||
SRC_TYPE *pOv, *pOvEnd;
|
||||
INT16 *psBtOut = (INT16 *)pDst;
|
||||
|
||||
memcpy (pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 2), pSrc, BTA_DM_PCM_OVERLAP_SIZE * 2);
|
||||
|
||||
pOv = (SRC_TYPE *)(pOverlapArea + BTA_DM_PCM_OVERLAP_SIZE);
|
||||
pOvEnd = (SRC_TYPE *)(pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 3));
|
||||
|
||||
pIn = (SRC_TYPE *)(pSrc + BTA_DM_PCM_OVERLAP_SIZE);
|
||||
pInEnd = (SRC_TYPE *)(pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - BTA_DM_PCM_OVERLAP_SIZE);
|
||||
|
||||
if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_44100) {
|
||||
CONVERT_44100_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_44100_TO_BLUETOOTH(pIn, pInEnd);
|
||||
} else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_22050) {
|
||||
CONVERT_22050_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_22050_TO_BLUETOOTH(pIn, pInEnd);
|
||||
} else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_11025) {
|
||||
CONVERT_11025_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_11025_TO_BLUETOOTH(pIn, pInEnd);
|
||||
}
|
||||
|
||||
memcpy (pOverlapArea, pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - \
|
||||
(BTA_DM_PCM_OVERLAP_SIZE * 2), BTA_DM_PCM_OVERLAP_SIZE * 2);
|
||||
|
||||
*pLastCurPos = CurrentPos;
|
||||
|
||||
return (psBtOut - (INT16 *)pDst);
|
||||
}
|
||||
|
||||
INT32 Convert_16M_ToBT_NoFilter (void *pSrc, void *pDst, UINT32 dwSrcSamples, UINT32 dwSrcSps)
|
||||
{
|
||||
INT32 CurrentPos;
|
||||
INT16 *psSrc = (INT16 *)pSrc;
|
||||
INT16 *psDst = (INT16 *)pDst;
|
||||
|
||||
// start at dwSpsSrc / 2, decrement by 8000
|
||||
//
|
||||
CurrentPos = (dwSrcSps >> 1);
|
||||
|
||||
while (dwSrcSamples--) {
|
||||
CurrentPos -= 8000;
|
||||
|
||||
if (CurrentPos >= 0) {
|
||||
psSrc++;
|
||||
} else {
|
||||
*psDst++ = *psSrc++;
|
||||
|
||||
CurrentPos += dwSrcSps;
|
||||
}
|
||||
}
|
||||
|
||||
return (psDst - (INT16 *)pDst);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
#undef SRC_CHANNELS
|
||||
#undef SRC_SAMPLE
|
||||
#undef SRC_TYPE
|
||||
|
||||
#define SRC_TYPE UINT8
|
||||
#define SRC_CHANNELS 2
|
||||
#define SRC_SAMPLE(x) ((((pS[x * 2] - 0x80) << 8) + ((pS[(x * 2) + 1] - 0x80) << 8)) >> 1)
|
||||
|
||||
INT32 Convert_8S_ToBT_Filtered (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
|
||||
UINT32 dwSrcSps, INT32 *pLastCurPos, UINT8 *pOverlapArea)
|
||||
{
|
||||
INT32 CurrentPos = *pLastCurPos;
|
||||
SRC_TYPE *pIn, *pInEnd;
|
||||
SRC_TYPE *pOv, *pOvEnd;
|
||||
INT16 *psBtOut = (INT16 *)pDst;
|
||||
|
||||
#if BTA_DM_SCO_DEBUG
|
||||
APPL_TRACE_DEBUG("Convert_8S_ToBT_Filtered CurrentPos %d, SRC_TYPE %d, SRC_CHANNELS %d, \
|
||||
dwSrcSamples %d, dwSrcSps %d", CurrentPos, sizeof (SRC_TYPE), SRC_CHANNELS, \
|
||||
dwSrcSamples, dwSrcSps);
|
||||
#endif
|
||||
memcpy (pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 2), pSrc, BTA_DM_PCM_OVERLAP_SIZE * 2);
|
||||
|
||||
pOv = (SRC_TYPE *)(pOverlapArea + BTA_DM_PCM_OVERLAP_SIZE);
|
||||
pOvEnd = (SRC_TYPE *)(pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 3));
|
||||
|
||||
pIn = (SRC_TYPE *)(pSrc + BTA_DM_PCM_OVERLAP_SIZE);
|
||||
pInEnd = (SRC_TYPE *)(pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - BTA_DM_PCM_OVERLAP_SIZE);
|
||||
|
||||
if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_44100) {
|
||||
CONVERT_44100_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_44100_TO_BLUETOOTH(pIn, pInEnd);
|
||||
} else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_22050) {
|
||||
CONVERT_22050_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_22050_TO_BLUETOOTH(pIn, pInEnd);
|
||||
} else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_11025) {
|
||||
CONVERT_11025_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_11025_TO_BLUETOOTH(pIn, pInEnd);
|
||||
}
|
||||
|
||||
memcpy (pOverlapArea, pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - \
|
||||
(BTA_DM_PCM_OVERLAP_SIZE * 2), BTA_DM_PCM_OVERLAP_SIZE * 2);
|
||||
|
||||
*pLastCurPos = CurrentPos;
|
||||
|
||||
return (psBtOut - (INT16 *)pDst);
|
||||
}
|
||||
|
||||
INT32 Convert_8S_ToBT_NoFilter (void *pSrc, void *pDst, UINT32 dwSrcSamples, UINT32 dwSrcSps)
|
||||
{
|
||||
INT32 CurrentPos;
|
||||
UINT8 *pbSrc = (UINT8 *)pSrc;
|
||||
INT16 *psDst = (INT16 *)pDst;
|
||||
INT16 sWorker, sWorker2;
|
||||
|
||||
// start at dwSpsSrc / 2, decrement by 8000
|
||||
//
|
||||
CurrentPos = (dwSrcSps >> 1);
|
||||
|
||||
while (dwSrcSamples--) {
|
||||
CurrentPos -= 8000;
|
||||
|
||||
if (CurrentPos >= 0) {
|
||||
pbSrc += 2;
|
||||
} else {
|
||||
sWorker = *(unsigned char *)pbSrc;
|
||||
sWorker -= 0x80;
|
||||
sWorker <<= 8;
|
||||
pbSrc++;
|
||||
|
||||
sWorker2 = *(unsigned char *)pbSrc;
|
||||
sWorker2 -= 0x80;
|
||||
sWorker2 <<= 8;
|
||||
pbSrc++;
|
||||
|
||||
sWorker += sWorker2;
|
||||
sWorker >>= 1;
|
||||
|
||||
*psDst++ = sWorker;
|
||||
|
||||
CurrentPos += dwSrcSps;
|
||||
}
|
||||
}
|
||||
|
||||
return (psDst - (INT16 *)pDst);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
#undef SRC_CHANNELS
|
||||
#undef SRC_SAMPLE
|
||||
#undef SRC_TYPE
|
||||
|
||||
#define SRC_TYPE INT16
|
||||
#define SRC_CHANNELS 2
|
||||
#define SRC_SAMPLE(x) ((pS[x * 2] + pS[(x * 2) + 1]) >> 1)
|
||||
|
||||
INT32 Convert_16S_ToBT_Filtered (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
|
||||
UINT32 dwSrcSps, INT32 *pLastCurPos, UINT8 *pOverlapArea)
|
||||
{
|
||||
INT32 CurrentPos = *pLastCurPos;
|
||||
SRC_TYPE *pIn, *pInEnd;
|
||||
SRC_TYPE *pOv, *pOvEnd;
|
||||
INT16 *psBtOut = (INT16 *)pDst;
|
||||
|
||||
memcpy (pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 2), pSrc, BTA_DM_PCM_OVERLAP_SIZE * 2);
|
||||
|
||||
pOv = (SRC_TYPE *)(pOverlapArea + BTA_DM_PCM_OVERLAP_SIZE);
|
||||
pOvEnd = (SRC_TYPE *)(pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 3));
|
||||
|
||||
pIn = (SRC_TYPE *)(pSrc + BTA_DM_PCM_OVERLAP_SIZE);
|
||||
pInEnd = (SRC_TYPE *)(pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - BTA_DM_PCM_OVERLAP_SIZE);
|
||||
|
||||
if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_44100) {
|
||||
CONVERT_44100_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_44100_TO_BLUETOOTH(pIn, pInEnd);
|
||||
} else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_22050) {
|
||||
CONVERT_22050_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_22050_TO_BLUETOOTH(pIn, pInEnd);
|
||||
} else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_11025) {
|
||||
CONVERT_11025_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_11025_TO_BLUETOOTH(pIn, pInEnd);
|
||||
}
|
||||
|
||||
memcpy (pOverlapArea, pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - \
|
||||
(BTA_DM_PCM_OVERLAP_SIZE * 2), BTA_DM_PCM_OVERLAP_SIZE * 2);
|
||||
|
||||
*pLastCurPos = CurrentPos;
|
||||
|
||||
return (psBtOut - (INT16 *)pDst);
|
||||
}
|
||||
|
||||
INT32 Convert_16S_ToBT_NoFilter (void *pSrc, void *pDst, UINT32 dwSrcSamples, UINT32 dwSrcSps)
|
||||
{
|
||||
INT32 CurrentPos;
|
||||
INT16 *psSrc = (INT16 *)pSrc;
|
||||
INT16 *psDst = (INT16 *)pDst;
|
||||
INT16 sWorker;
|
||||
|
||||
// start at dwSpsSrc / 2, decrement by 8000
|
||||
//
|
||||
CurrentPos = (dwSrcSps >> 1);
|
||||
|
||||
while (dwSrcSamples--) {
|
||||
CurrentPos -= 8000;
|
||||
|
||||
if (CurrentPos >= 0) {
|
||||
psSrc += 2;
|
||||
} else {
|
||||
/* CR 82894, to avoid overflow, divide before add */
|
||||
sWorker = ((*psSrc) >> 1 );
|
||||
psSrc++;
|
||||
sWorker += ((*psSrc) >> 1 );
|
||||
psSrc++;
|
||||
|
||||
*psDst++ = sWorker;
|
||||
|
||||
CurrentPos += dwSrcSps;
|
||||
}
|
||||
}
|
||||
|
||||
return (psDst - (INT16 *)pDst);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_DmPcmInitSamples
|
||||
**
|
||||
** Description initialize the down sample converter.
|
||||
**
|
||||
** src_sps: original samples per second (source audio data)
|
||||
** (ex. 44100, 48000)
|
||||
** bits: number of bits per pcm sample (16)
|
||||
** n_channels: number of channels (i.e. mono(1), stereo(2)...)
|
||||
**
|
||||
** Returns none
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_DmPcmInitSamples (UINT32 src_sps, UINT32 bits, UINT32 n_channels)
|
||||
{
|
||||
tBTA_DM_PCM_RESAMPLE_CB *p_cb = &bta_dm_pcm_cb;
|
||||
|
||||
p_cb->cur_pos = src_sps / 2;
|
||||
p_cb->src_sps = src_sps;
|
||||
p_cb->bits = bits;
|
||||
p_cb->n_channels = n_channels;
|
||||
p_cb->sample_size = 2;
|
||||
p_cb->divisor = 2;
|
||||
|
||||
memset(p_cb->overlap_area, 0, sizeof(p_cb->overlap_area) );
|
||||
|
||||
if ((src_sps == BTA_DM_PCM_SMPL_RATE_44100) ||
|
||||
(src_sps == BTA_DM_PCM_SMPL_RATE_22050) ||
|
||||
(src_sps == BTA_DM_PCM_SMPL_RATE_11025)) {
|
||||
p_cb->can_be_filtered = 1;
|
||||
} else {
|
||||
p_cb->can_be_filtered = 0;
|
||||
}
|
||||
|
||||
#if BTA_DM_SCO_DEBUG
|
||||
APPL_TRACE_DEBUG("bta_dm_pcm_init_samples: n_channels = %d bits = %d", n_channels, bits);
|
||||
#endif
|
||||
if (n_channels == 1) {
|
||||
/* mono */
|
||||
if (bits == 8) {
|
||||
p_cb->filter = (PCONVERT_TO_BT_FILTERED) Convert_8M_ToBT_Filtered;
|
||||
p_cb->nofilter = (PCONVERT_TO_BT_NOFILTER) Convert_8M_ToBT_NoFilter;
|
||||
p_cb->divisor = 1;
|
||||
} else {
|
||||
p_cb->filter = (PCONVERT_TO_BT_FILTERED) Convert_16M_ToBT_Filtered;
|
||||
p_cb->nofilter = (PCONVERT_TO_BT_NOFILTER) Convert_16M_ToBT_NoFilter;
|
||||
}
|
||||
} else {
|
||||
/* stereo */
|
||||
if (bits == 8) {
|
||||
p_cb->filter = (PCONVERT_TO_BT_FILTERED) Convert_8S_ToBT_Filtered;
|
||||
p_cb->nofilter = (PCONVERT_TO_BT_NOFILTER) Convert_8S_ToBT_NoFilter;
|
||||
} else {
|
||||
p_cb->filter = (PCONVERT_TO_BT_FILTERED) Convert_16S_ToBT_Filtered;
|
||||
p_cb->nofilter = (PCONVERT_TO_BT_NOFILTER) Convert_16S_ToBT_NoFilter;
|
||||
p_cb->divisor = 4;
|
||||
}
|
||||
}
|
||||
|
||||
#if BTA_DM_SCO_DEBUG
|
||||
APPL_TRACE_DEBUG("bta_pcm_init_dwn_sample: cur_pos %d, src_sps %d", \
|
||||
p_cb->cur_pos, p_cb->src_sps);
|
||||
APPL_TRACE_DEBUG("bta_pcm_init_dwn_sample: bits %d, n_channels %d, sample_size %d, ", \
|
||||
p_cb->bits, p_cb->n_channels, p_cb->sample_size);
|
||||
APPL_TRACE_DEBUG("bta_pcm_init_dwn_sample: can_be_filtered %d, n_channels: %d, \
|
||||
divisor %d", p_cb->can_be_filtered, p_cb->n_channels, p_cb->divisor);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/**************************************************************************************
|
||||
** Function BTA_DmPcmResample
|
||||
**
|
||||
** Description Down sampling utility to convert higher sampling rate into 8K/16bits
|
||||
** PCM samples.
|
||||
**
|
||||
** Parameters p_src: pointer to the buffer where the original sampling PCM
|
||||
** are stored.
|
||||
** in_bytes: Length of the input PCM sample buffer in byte.
|
||||
** p_dst: pointer to the buffer which is to be used to store
|
||||
** the converted PCM samples.
|
||||
**
|
||||
**
|
||||
** Returns INT32: number of samples converted.
|
||||
**
|
||||
**************************************************************************************/
|
||||
INT32 BTA_DmPcmResample (void *p_src, UINT32 in_bytes, void *p_dst)
|
||||
{
|
||||
UINT32 out_sample;
|
||||
|
||||
#if BTA_DM_SCO_DEBUG
|
||||
APPL_TRACE_DEBUG("bta_pcm_resample : insamples %d", (in_bytes / bta_dm_pcm_cb.divisor));
|
||||
#endif
|
||||
if (bta_dm_pcm_cb.can_be_filtered) {
|
||||
out_sample = (*bta_dm_pcm_cb.filter) (p_src, p_dst, (in_bytes / bta_dm_pcm_cb.divisor),
|
||||
bta_dm_pcm_cb.src_sps, (INT32 *) &bta_dm_pcm_cb.cur_pos, bta_dm_pcm_cb.overlap_area);
|
||||
} else {
|
||||
out_sample = (*bta_dm_pcm_cb.nofilter) (p_src, p_dst,
|
||||
(in_bytes / bta_dm_pcm_cb.divisor), bta_dm_pcm_cb.src_sps);
|
||||
}
|
||||
|
||||
#if BTA_DM_SCO_DEBUG
|
||||
APPL_TRACE_DEBUG("bta_pcm_resample : outsamples %d", out_sample);
|
||||
#endif
|
||||
|
||||
return (out_sample * bta_dm_pcm_cb.sample_size);
|
||||
}
|
||||
#endif
|
||||
2202
components/bt/bluedroid/bta/gatt/bta_gattc_act.c
Normal file
2202
components/bt/bluedroid/bta/gatt/bta_gattc_act.c
Normal file
File diff suppressed because it is too large
Load Diff
1062
components/bt/bluedroid/bta/gatt/bta_gattc_api.c
Normal file
1062
components/bt/bluedroid/bta/gatt/bta_gattc_api.c
Normal file
File diff suppressed because it is too large
Load Diff
1508
components/bt/bluedroid/bta/gatt/bta_gattc_cache.c
Normal file
1508
components/bt/bluedroid/bta/gatt/bta_gattc_cache.c
Normal file
File diff suppressed because it is too large
Load Diff
136
components/bt/bluedroid/bta/gatt/bta_gattc_ci.c
Normal file
136
components/bt/bluedroid/bta/gatt/bta_gattc_ci.c
Normal file
@@ -0,0 +1,136 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the implementation file for the GATT call-in functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
|
||||
#if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "bta_api.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_gattc_ci.h"
|
||||
#include "gki.h"
|
||||
#include "utl.h"
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_ci_cache_open
|
||||
**
|
||||
** Description This function sends an event to indicate server cache open
|
||||
** completed.
|
||||
**
|
||||
** Parameters server_bda - server BDA of this cache.
|
||||
** status - BTA_GATT_OK if full buffer of data,
|
||||
** BTA_GATT_FAIL if an error has occurred.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gattc_ci_cache_open(BD_ADDR server_bda, UINT16 evt, tBTA_GATT_STATUS status,
|
||||
UINT16 conn_id)
|
||||
{
|
||||
tBTA_GATTC_CI_EVT *p_evt;
|
||||
UNUSED(server_bda);
|
||||
|
||||
if ((p_evt = (tBTA_GATTC_CI_EVT *) GKI_getbuf(sizeof(tBTA_GATTC_CI_EVT))) != NULL) {
|
||||
p_evt->hdr.event = evt;
|
||||
p_evt->hdr.layer_specific = conn_id;
|
||||
|
||||
p_evt->status = status;
|
||||
bta_sys_sendmsg(p_evt);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_ci_cache_load
|
||||
**
|
||||
** Description This function sends an event to BTA indicating the phone has
|
||||
** load the servere cache and ready to send it to the stack.
|
||||
**
|
||||
** Parameters server_bda - server BDA of this cache.
|
||||
** num_bytes_read - number of bytes read into the buffer
|
||||
** specified in the read callout-function.
|
||||
** status - BTA_GATT_OK if full buffer of data,
|
||||
** BTA_GATT_FAIL if an error has occurred.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gattc_ci_cache_load(BD_ADDR server_bda, UINT16 evt, UINT16 num_attr,
|
||||
tBTA_GATTC_NV_ATTR *p_attr, tBTA_GATT_STATUS status,
|
||||
UINT16 conn_id)
|
||||
{
|
||||
tBTA_GATTC_CI_LOAD *p_evt;
|
||||
UNUSED(server_bda);
|
||||
|
||||
if ((p_evt = (tBTA_GATTC_CI_LOAD *) GKI_getbuf(sizeof(tBTA_GATTC_CI_LOAD))) != NULL) {
|
||||
memset(p_evt, 0, sizeof(tBTA_GATTC_CI_LOAD));
|
||||
|
||||
p_evt->hdr.event = evt;
|
||||
p_evt->hdr.layer_specific = conn_id;
|
||||
|
||||
p_evt->status = status;
|
||||
p_evt->num_attr = (num_attr > BTA_GATTC_NV_LOAD_MAX) ? BTA_GATTC_NV_LOAD_MAX : num_attr;
|
||||
|
||||
if (p_evt->num_attr > 0 && p_attr != NULL) {
|
||||
memcpy(p_evt->attr, p_attr, p_evt->num_attr * sizeof(tBTA_GATTC_NV_ATTR));
|
||||
}
|
||||
|
||||
bta_sys_sendmsg(p_evt);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_ci_cache_save
|
||||
**
|
||||
** Description This function sends an event to BTA indicating the phone has
|
||||
** save the servere cache.
|
||||
**
|
||||
** Parameters server_bda - server BDA of this cache.
|
||||
** evt - callin event code.
|
||||
** status - BTA_GATT_OK if full buffer of data,
|
||||
** BTA_GATT_ERROR if an error has occurred.
|
||||
*8 conn_id - for this NV operation for.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gattc_ci_cache_save(BD_ADDR server_bda, UINT16 evt, tBTA_GATT_STATUS status,
|
||||
UINT16 conn_id)
|
||||
{
|
||||
tBTA_GATTC_CI_EVT *p_evt;
|
||||
UNUSED(server_bda);
|
||||
|
||||
if ((p_evt = (tBTA_GATTC_CI_EVT *) GKI_getbuf(sizeof(tBTA_GATTC_CI_EVT))) != NULL) {
|
||||
p_evt->hdr.event = evt;
|
||||
p_evt->hdr.layer_specific = conn_id;
|
||||
|
||||
p_evt->status = status;
|
||||
bta_sys_sendmsg(p_evt);
|
||||
}
|
||||
}
|
||||
#endif /* BTA_GATT_INCLUDED */
|
||||
525
components/bt/bluedroid/bta/gatt/bta_gattc_main.c
Normal file
525
components/bt/bluedroid/bta/gatt/bta_gattc_main.c
Normal file
@@ -0,0 +1,525 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the GATT client main functions and state machine.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
|
||||
#if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "bta_gattc_int.h"
|
||||
#include "gki.h"
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and types
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/* state machine action enumeration list */
|
||||
enum {
|
||||
BTA_GATTC_OPEN,
|
||||
BTA_GATTC_OPEN_FAIL,
|
||||
BTA_GATTC_OPEN_ERROR,
|
||||
BTA_GATTC_CANCEL_OPEN,
|
||||
BTA_GATTC_CANCEL_OPEN_OK,
|
||||
BTA_GATTC_CANCEL_OPEN_ERROR,
|
||||
BTA_GATTC_CONN,
|
||||
BTA_GATTC_START_DISCOVER,
|
||||
BTA_GATTC_DISC_CMPL,
|
||||
|
||||
BTA_GATTC_Q_CMD,
|
||||
BTA_GATTC_CLOSE,
|
||||
BTA_GATTC_CLOSE_FAIL,
|
||||
BTA_GATTC_READ,
|
||||
BTA_GATTC_WRITE,
|
||||
|
||||
BTA_GATTC_OP_CMPL,
|
||||
BTA_GATTC_SEARCH,
|
||||
BTA_GATTC_FAIL,
|
||||
BTA_GATTC_CONFIRM,
|
||||
BTA_GATTC_EXEC,
|
||||
BTA_GATTC_READ_MULTI,
|
||||
BTA_GATTC_CI_OPEN,
|
||||
BTA_GATTC_CI_LOAD,
|
||||
BTA_GATTC_CI_SAVE,
|
||||
BTA_GATTC_CACHE_OPEN,
|
||||
BTA_GATTC_IGNORE_OP_CMPL,
|
||||
BTA_GATTC_DISC_CLOSE,
|
||||
BTA_GATTC_RESTART_DISCOVER,
|
||||
BTA_GATTC_CFG_MTU,
|
||||
|
||||
BTA_GATTC_IGNORE
|
||||
};
|
||||
/* type for action functions */
|
||||
typedef void (*tBTA_GATTC_ACTION)(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
|
||||
/* action function list */
|
||||
const tBTA_GATTC_ACTION bta_gattc_action[] = {
|
||||
bta_gattc_open,
|
||||
bta_gattc_open_fail,
|
||||
bta_gattc_open_error,
|
||||
bta_gattc_cancel_open,
|
||||
bta_gattc_cancel_open_ok,
|
||||
bta_gattc_cancel_open_error,
|
||||
bta_gattc_conn,
|
||||
bta_gattc_start_discover,
|
||||
bta_gattc_disc_cmpl,
|
||||
|
||||
bta_gattc_q_cmd,
|
||||
bta_gattc_close,
|
||||
bta_gattc_close_fail,
|
||||
bta_gattc_read,
|
||||
bta_gattc_write,
|
||||
|
||||
bta_gattc_op_cmpl,
|
||||
bta_gattc_search,
|
||||
bta_gattc_fail,
|
||||
bta_gattc_confirm,
|
||||
bta_gattc_execute,
|
||||
bta_gattc_read_multi,
|
||||
bta_gattc_ci_open,
|
||||
bta_gattc_ci_load,
|
||||
bta_gattc_ci_save,
|
||||
bta_gattc_cache_open,
|
||||
bta_gattc_ignore_op_cmpl,
|
||||
bta_gattc_disc_close,
|
||||
bta_gattc_restart_discover,
|
||||
bta_gattc_cfg_mtu
|
||||
};
|
||||
|
||||
|
||||
/* state table information */
|
||||
#define BTA_GATTC_ACTIONS 1 /* number of actions */
|
||||
#define BTA_GATTC_NEXT_STATE 1 /* position of next state */
|
||||
#define BTA_GATTC_NUM_COLS 2 /* number of columns in state tables */
|
||||
|
||||
/* state table for idle state */
|
||||
static const UINT8 bta_gattc_st_idle[][BTA_GATTC_NUM_COLS] = {
|
||||
/* Event Action 1 Next state */
|
||||
/* BTA_GATTC_API_OPEN_EVT */ {BTA_GATTC_OPEN, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_INT_OPEN_FAIL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_API_CANCEL_OPEN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_INT_CANCEL_OPEN_OK_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
|
||||
/* BTA_GATTC_API_READ_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_API_WRITE_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_API_EXEC_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_API_CFG_MTU_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
|
||||
/* BTA_GATTC_API_CLOSE_EVT */ {BTA_GATTC_CLOSE_FAIL, BTA_GATTC_IDLE_ST},
|
||||
|
||||
/* BTA_GATTC_API_SEARCH_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_API_CONFIRM_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_API_READ_MULTI_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_API_REFRESH_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
|
||||
/* BTA_GATTC_INT_CONN_EVT */ {BTA_GATTC_CONN, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_INT_DISCOVER_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_DISCOVER_CMPL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_OP_CMPL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
|
||||
|
||||
/* ===> for cache loading, saving */
|
||||
/* BTA_GATTC_START_CACHE_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_CI_CACHE_OPEN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_CI_CACHE_LOAD_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_CI_CACHE_SAVE_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST}
|
||||
};
|
||||
|
||||
/* state table for wait for open state */
|
||||
static const UINT8 bta_gattc_st_w4_conn[][BTA_GATTC_NUM_COLS] = {
|
||||
/* Event Action 1 Next state */
|
||||
/* BTA_GATTC_API_OPEN_EVT */ {BTA_GATTC_OPEN, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_INT_OPEN_FAIL_EVT */ {BTA_GATTC_OPEN_FAIL, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_API_CANCEL_OPEN_EVT */ {BTA_GATTC_CANCEL_OPEN, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_INT_CANCEL_OPEN_OK_EVT */ {BTA_GATTC_CANCEL_OPEN_OK, BTA_GATTC_IDLE_ST},
|
||||
|
||||
/* BTA_GATTC_API_READ_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_API_WRITE_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_API_EXEC_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_API_CFG_MTU_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
|
||||
|
||||
/* BTA_GATTC_API_CLOSE_EVT */ {BTA_GATTC_CANCEL_OPEN, BTA_GATTC_W4_CONN_ST},
|
||||
|
||||
/* BTA_GATTC_API_SEARCH_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_API_CONFIRM_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_API_READ_MULTI_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_API_REFRESH_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
|
||||
|
||||
/* BTA_GATTC_INT_CONN_EVT */ {BTA_GATTC_CONN, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_INT_DISCOVER_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_DISCOVER_CMPL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_OP_CMPL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_OPEN_FAIL, BTA_GATTC_IDLE_ST},
|
||||
|
||||
/* ===> for cache loading, saving */
|
||||
/* BTA_GATTC_START_CACHE_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_CI_CACHE_OPEN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_CI_CACHE_LOAD_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_CI_CACHE_SAVE_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST}
|
||||
};
|
||||
|
||||
/* state table for open state */
|
||||
static const UINT8 bta_gattc_st_connected[][BTA_GATTC_NUM_COLS] = {
|
||||
/* Event Action 1 Next state */
|
||||
/* BTA_GATTC_API_OPEN_EVT */ {BTA_GATTC_OPEN, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_INT_OPEN_FAIL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_API_CANCEL_OPEN_EVT */ {BTA_GATTC_CANCEL_OPEN_ERROR, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_INT_CANCEL_OPEN_OK_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_CONN_ST},
|
||||
|
||||
/* BTA_GATTC_API_READ_EVT */ {BTA_GATTC_READ, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_API_WRITE_EVT */ {BTA_GATTC_WRITE, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_API_EXEC_EVT */ {BTA_GATTC_EXEC, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_API_CFG_MTU_EVT */ {BTA_GATTC_CFG_MTU, BTA_GATTC_CONN_ST},
|
||||
|
||||
/* BTA_GATTC_API_CLOSE_EVT */ {BTA_GATTC_CLOSE, BTA_GATTC_IDLE_ST},
|
||||
|
||||
/* BTA_GATTC_API_SEARCH_EVT */ {BTA_GATTC_SEARCH, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_API_CONFIRM_EVT */ {BTA_GATTC_CONFIRM, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_API_READ_MULTI_EVT */ {BTA_GATTC_READ_MULTI, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_API_REFRESH_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_CONN_ST},
|
||||
|
||||
/* BTA_GATTC_INT_CONN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_INT_DISCOVER_EVT */ {BTA_GATTC_START_DISCOVER, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_DISCOVER_CMPL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_OP_CMPL_EVT */ {BTA_GATTC_OP_CMPL, BTA_GATTC_CONN_ST},
|
||||
|
||||
/* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_CLOSE, BTA_GATTC_IDLE_ST},
|
||||
|
||||
/* ===> for cache loading, saving */
|
||||
/* BTA_GATTC_START_CACHE_EVT */ {BTA_GATTC_CACHE_OPEN, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_CI_CACHE_OPEN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_CI_CACHE_LOAD_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_CI_CACHE_SAVE_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_CONN_ST}
|
||||
};
|
||||
|
||||
/* state table for discover state */
|
||||
static const UINT8 bta_gattc_st_discover[][BTA_GATTC_NUM_COLS] = {
|
||||
/* Event Action 1 Next state */
|
||||
/* BTA_GATTC_API_OPEN_EVT */ {BTA_GATTC_OPEN, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_INT_OPEN_FAIL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_API_CANCEL_OPEN_EVT */ {BTA_GATTC_CANCEL_OPEN_ERROR, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_INT_CANCEL_OPEN_OK_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_DISCOVER_ST},
|
||||
|
||||
/* BTA_GATTC_API_READ_EVT */ {BTA_GATTC_Q_CMD, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_API_WRITE_EVT */ {BTA_GATTC_Q_CMD, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_API_EXEC_EVT */ {BTA_GATTC_Q_CMD, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_API_CFG_MTU_EVT */ {BTA_GATTC_Q_CMD, BTA_GATTC_DISCOVER_ST},
|
||||
|
||||
/* BTA_GATTC_API_CLOSE_EVT */ {BTA_GATTC_DISC_CLOSE, BTA_GATTC_DISCOVER_ST},
|
||||
|
||||
/* BTA_GATTC_API_SEARCH_EVT */ {BTA_GATTC_Q_CMD, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_API_CONFIRM_EVT */ {BTA_GATTC_CONFIRM, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_API_READ_MULTI_EVT */ {BTA_GATTC_Q_CMD, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_API_REFRESH_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_DISCOVER_ST},
|
||||
|
||||
/* BTA_GATTC_INT_CONN_EVT */ {BTA_GATTC_CONN, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_INT_DISCOVER_EVT */ {BTA_GATTC_RESTART_DISCOVER, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_DISCOVER_CMPL_EVT */ {BTA_GATTC_DISC_CMPL, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_OP_CMPL_EVT */ {BTA_GATTC_IGNORE_OP_CMPL, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_CLOSE, BTA_GATTC_IDLE_ST},
|
||||
|
||||
/* ===> for cache loading, saving */
|
||||
/* BTA_GATTC_START_CACHE_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_CI_CACHE_OPEN_EVT */ {BTA_GATTC_CI_OPEN, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_CI_CACHE_LOAD_EVT */ {BTA_GATTC_CI_LOAD, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_CI_CACHE_SAVE_EVT */ {BTA_GATTC_CI_SAVE, BTA_GATTC_DISCOVER_ST}
|
||||
};
|
||||
|
||||
/* type for state table */
|
||||
typedef const UINT8 (*tBTA_GATTC_ST_TBL)[BTA_GATTC_NUM_COLS];
|
||||
|
||||
/* state table */
|
||||
const tBTA_GATTC_ST_TBL bta_gattc_st_tbl[] = {
|
||||
bta_gattc_st_idle,
|
||||
bta_gattc_st_w4_conn,
|
||||
bta_gattc_st_connected,
|
||||
bta_gattc_st_discover
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
** Global data
|
||||
*****************************************************************************/
|
||||
|
||||
/* GATTC control block */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
tBTA_GATTC_CB bta_gattc_cb;
|
||||
#endif
|
||||
|
||||
#if BTA_GATT_DEBUG == TRUE
|
||||
static char *gattc_evt_code(tBTA_GATTC_INT_EVT evt_code);
|
||||
static char *gattc_state_code(tBTA_GATTC_STATE state_code);
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_sm_execute
|
||||
**
|
||||
** Description State machine event handling function for GATTC
|
||||
**
|
||||
**
|
||||
** Returns BOOLEAN : TRUE if queued client request buffer can be immediately released
|
||||
** else FALSE
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data)
|
||||
{
|
||||
tBTA_GATTC_ST_TBL state_table;
|
||||
UINT8 action;
|
||||
int i;
|
||||
BOOLEAN rt = TRUE;
|
||||
#if BTA_GATT_DEBUG == TRUE
|
||||
tBTA_GATTC_STATE in_state = p_clcb->state;
|
||||
UINT16 in_event = event;
|
||||
APPL_TRACE_DEBUG("bta_gattc_sm_execute: State 0x%02x [%s], Event 0x%x[%s]", in_state,
|
||||
gattc_state_code(in_state),
|
||||
in_event,
|
||||
gattc_evt_code(in_event));
|
||||
#endif
|
||||
|
||||
|
||||
/* look up the state table for the current state */
|
||||
state_table = bta_gattc_st_tbl[p_clcb->state];
|
||||
|
||||
event &= 0x00FF;
|
||||
|
||||
/* set next state */
|
||||
p_clcb->state = state_table[event][BTA_GATTC_NEXT_STATE];
|
||||
|
||||
/* execute action functions */
|
||||
for (i = 0; i < BTA_GATTC_ACTIONS; i++) {
|
||||
if ((action = state_table[event][i]) != BTA_GATTC_IGNORE) {
|
||||
(*bta_gattc_action[action])(p_clcb, p_data);
|
||||
if (p_clcb->p_q_cmd == p_data) {
|
||||
/* buffer is queued, don't free in the bta dispatcher.
|
||||
* we free it ourselves when a completion event is received.
|
||||
*/
|
||||
rt = FALSE;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if BTA_GATT_DEBUG == TRUE
|
||||
if (in_state != p_clcb->state) {
|
||||
APPL_TRACE_DEBUG("GATTC State Change: [%s] -> [%s] after Event [%s]",
|
||||
gattc_state_code(in_state),
|
||||
gattc_state_code(p_clcb->state),
|
||||
gattc_evt_code(in_event));
|
||||
}
|
||||
#endif
|
||||
return rt;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_hdl_event
|
||||
**
|
||||
** Description GATT client main event handling function.
|
||||
**
|
||||
**
|
||||
** Returns BOOLEAN
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg)
|
||||
{
|
||||
tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
|
||||
tBTA_GATTC_CLCB *p_clcb = NULL;
|
||||
tBTA_GATTC_RCB *p_clreg;
|
||||
BOOLEAN rt = TRUE;
|
||||
#if BTA_GATT_DEBUG == TRUE
|
||||
APPL_TRACE_DEBUG("bta_gattc_hdl_event: Event [%s]\n", gattc_evt_code(p_msg->event));
|
||||
#endif
|
||||
switch (p_msg->event) {
|
||||
case BTA_GATTC_API_DISABLE_EVT:
|
||||
bta_gattc_disable(p_cb);
|
||||
break;
|
||||
|
||||
case BTA_GATTC_API_REG_EVT:
|
||||
bta_gattc_register(p_cb, (tBTA_GATTC_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTC_INT_START_IF_EVT:
|
||||
bta_gattc_start_if(p_cb, (tBTA_GATTC_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTC_API_DEREG_EVT:
|
||||
p_clreg = bta_gattc_cl_get_regcb(((tBTA_GATTC_DATA *)p_msg)->api_dereg.client_if);
|
||||
bta_gattc_deregister(p_cb, p_clreg);
|
||||
break;
|
||||
|
||||
case BTA_GATTC_API_OPEN_EVT:
|
||||
bta_gattc_process_api_open(p_cb, (tBTA_GATTC_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTC_API_CANCEL_OPEN_EVT:
|
||||
bta_gattc_process_api_open_cancel(p_cb, (tBTA_GATTC_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTC_API_REFRESH_EVT:
|
||||
bta_gattc_process_api_refresh(p_cb, (tBTA_GATTC_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
#if BLE_INCLUDED == TRUE
|
||||
case BTA_GATTC_API_LISTEN_EVT:
|
||||
bta_gattc_listen(p_cb, (tBTA_GATTC_DATA *) p_msg);
|
||||
break;
|
||||
case BTA_GATTC_API_BROADCAST_EVT:
|
||||
bta_gattc_broadcast(p_cb, (tBTA_GATTC_DATA *) p_msg);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case BTA_GATTC_ENC_CMPL_EVT:
|
||||
bta_gattc_process_enc_cmpl(p_cb, (tBTA_GATTC_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (p_msg->event == BTA_GATTC_INT_CONN_EVT) {
|
||||
p_clcb = bta_gattc_find_int_conn_clcb((tBTA_GATTC_DATA *) p_msg);
|
||||
} else if (p_msg->event == BTA_GATTC_INT_DISCONN_EVT) {
|
||||
p_clcb = bta_gattc_find_int_disconn_clcb((tBTA_GATTC_DATA *) p_msg);
|
||||
} else {
|
||||
p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->layer_specific);
|
||||
}
|
||||
|
||||
if (p_clcb != NULL) {
|
||||
rt = bta_gattc_sm_execute(p_clcb, p_msg->event, (tBTA_GATTC_DATA *) p_msg);
|
||||
} else {
|
||||
APPL_TRACE_DEBUG("Ignore unknown conn ID: %d\n", p_msg->layer_specific);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Debug Functions
|
||||
*****************************************************************************/
|
||||
#if BTA_GATT_DEBUG == TRUE
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function gattc_evt_code
|
||||
**
|
||||
** Description
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static char *gattc_evt_code(tBTA_GATTC_INT_EVT evt_code)
|
||||
{
|
||||
switch (evt_code) {
|
||||
case BTA_GATTC_API_OPEN_EVT:
|
||||
return "BTA_GATTC_API_OPEN_EVT";
|
||||
case BTA_GATTC_INT_OPEN_FAIL_EVT:
|
||||
return "BTA_GATTC_INT_OPEN_FAIL_EVT";
|
||||
case BTA_GATTC_API_CANCEL_OPEN_EVT:
|
||||
return "BTA_GATTC_API_CANCEL_OPEN_EVT";
|
||||
case BTA_GATTC_INT_CANCEL_OPEN_OK_EVT:
|
||||
return "BTA_GATTC_INT_CANCEL_OPEN_OK_EVT";
|
||||
case BTA_GATTC_API_READ_EVT:
|
||||
return "BTA_GATTC_API_READ_EVT";
|
||||
case BTA_GATTC_API_WRITE_EVT:
|
||||
return "BTA_GATTC_API_WRITE_EVT";
|
||||
case BTA_GATTC_API_EXEC_EVT:
|
||||
return "BTA_GATTC_API_EXEC_EVT";
|
||||
case BTA_GATTC_API_CLOSE_EVT:
|
||||
return "BTA_GATTC_API_CLOSE_EVT";
|
||||
case BTA_GATTC_API_SEARCH_EVT:
|
||||
return "BTA_GATTC_API_SEARCH_EVT";
|
||||
case BTA_GATTC_API_CONFIRM_EVT:
|
||||
return "BTA_GATTC_API_CONFIRM_EVT";
|
||||
case BTA_GATTC_API_READ_MULTI_EVT:
|
||||
return "BTA_GATTC_API_READ_MULTI_EVT";
|
||||
case BTA_GATTC_INT_CONN_EVT:
|
||||
return "BTA_GATTC_INT_CONN_EVT";
|
||||
case BTA_GATTC_INT_DISCOVER_EVT:
|
||||
return "BTA_GATTC_INT_DISCOVER_EVT";
|
||||
case BTA_GATTC_DISCOVER_CMPL_EVT:
|
||||
return "BTA_GATTC_DISCOVER_CMPL_EVT";
|
||||
case BTA_GATTC_OP_CMPL_EVT:
|
||||
return "BTA_GATTC_OP_CMPL_EVT";
|
||||
case BTA_GATTC_INT_DISCONN_EVT:
|
||||
return "BTA_GATTC_INT_DISCONN_EVT";
|
||||
case BTA_GATTC_START_CACHE_EVT:
|
||||
return "BTA_GATTC_START_CACHE_EVT";
|
||||
case BTA_GATTC_CI_CACHE_OPEN_EVT:
|
||||
return "BTA_GATTC_CI_CACHE_OPEN_EVT";
|
||||
case BTA_GATTC_CI_CACHE_LOAD_EVT:
|
||||
return "BTA_GATTC_CI_CACHE_LOAD_EVT";
|
||||
case BTA_GATTC_CI_CACHE_SAVE_EVT:
|
||||
return "BTA_GATTC_CI_CACHE_SAVE_EVT";
|
||||
case BTA_GATTC_INT_START_IF_EVT:
|
||||
return "BTA_GATTC_INT_START_IF_EVT";
|
||||
case BTA_GATTC_API_REG_EVT:
|
||||
return "BTA_GATTC_API_REG_EVT";
|
||||
case BTA_GATTC_API_DEREG_EVT:
|
||||
return "BTA_GATTC_API_DEREG_EVT";
|
||||
case BTA_GATTC_API_REFRESH_EVT:
|
||||
return "BTA_GATTC_API_REFRESH_EVT";
|
||||
case BTA_GATTC_API_LISTEN_EVT:
|
||||
return "BTA_GATTC_API_LISTEN_EVT";
|
||||
case BTA_GATTC_API_DISABLE_EVT:
|
||||
return "BTA_GATTC_API_DISABLE_EVT";
|
||||
case BTA_GATTC_API_CFG_MTU_EVT:
|
||||
return "BTA_GATTC_API_CFG_MTU_EVT";
|
||||
default:
|
||||
return "unknown GATTC event code";
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function gattc_state_code
|
||||
**
|
||||
** Description
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static char *gattc_state_code(tBTA_GATTC_STATE state_code)
|
||||
{
|
||||
switch (state_code) {
|
||||
case BTA_GATTC_IDLE_ST:
|
||||
return "GATTC_IDLE_ST";
|
||||
case BTA_GATTC_W4_CONN_ST:
|
||||
return "GATTC_W4_CONN_ST";
|
||||
case BTA_GATTC_CONN_ST:
|
||||
return "GATTC_CONN_ST";
|
||||
case BTA_GATTC_DISCOVER_ST:
|
||||
return "GATTC_DISCOVER_ST";
|
||||
default:
|
||||
return "unknown GATTC state code";
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Debug Functions */
|
||||
#endif /* BTA_GATT_INCLUDED */
|
||||
928
components/bt/bluedroid/bta/gatt/bta_gattc_utils.c
Normal file
928
components/bt/bluedroid/bta/gatt/bta_gattc_utils.c
Normal file
@@ -0,0 +1,928 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the GATT client utility function.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
|
||||
#if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "bdaddr.h"
|
||||
// #include "btif/include/btif_util.h"
|
||||
#include "gki.h"
|
||||
#include "utl.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_gattc_int.h"
|
||||
#include "l2c_api.h"
|
||||
|
||||
#define LOG_TAG "bt_bta_gattc"
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
static const UINT8 base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
|
||||
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const BD_ADDR dummy_bda = {0, 0, 0, 0, 0, 0};
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatt_convert_uuid16_to_uuid128
|
||||
**
|
||||
** Description Convert a 16 bits UUID to be an standard 128 bits one.
|
||||
**
|
||||
** Returns TRUE if two uuid match; FALSE otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16)
|
||||
{
|
||||
UINT8 *p = &uuid_128[LEN_UUID_128 - 4];
|
||||
|
||||
memcpy (uuid_128, base_uuid, LEN_UUID_128);
|
||||
|
||||
UINT16_TO_STREAM(p, uuid_16);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_uuid_compare
|
||||
**
|
||||
** Description Compare two UUID to see if they are the same.
|
||||
**
|
||||
** Returns TRUE if two uuid match; FALSE otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_uuid_compare (tBT_UUID *p_src, tBT_UUID *p_tar, BOOLEAN is_precise)
|
||||
{
|
||||
UINT8 su[LEN_UUID_128], tu[LEN_UUID_128];
|
||||
UINT8 *ps, *pt;
|
||||
|
||||
/* any of the UUID is unspecified */
|
||||
if (p_src == 0 || p_tar == 0) {
|
||||
if (is_precise) {
|
||||
return FALSE;
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If both are 16-bit, we can do a simple compare */
|
||||
if (p_src->len == 2 && p_tar->len == 2) {
|
||||
return p_src->uu.uuid16 == p_tar->uu.uuid16;
|
||||
}
|
||||
|
||||
/* One or both of the UUIDs is 128-bit */
|
||||
if (p_src->len == LEN_UUID_16) {
|
||||
/* convert a 16 bits UUID to 128 bits value */
|
||||
bta_gatt_convert_uuid16_to_uuid128(su, p_src->uu.uuid16);
|
||||
ps = su;
|
||||
} else {
|
||||
ps = p_src->uu.uuid128;
|
||||
}
|
||||
|
||||
if (p_tar->len == LEN_UUID_16) {
|
||||
/* convert a 16 bits UUID to 128 bits value */
|
||||
bta_gatt_convert_uuid16_to_uuid128(tu, p_tar->uu.uuid16);
|
||||
pt = tu;
|
||||
} else {
|
||||
pt = p_tar->uu.uuid128;
|
||||
}
|
||||
|
||||
return (memcmp(ps, pt, LEN_UUID_128) == 0);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_cl_get_regcb
|
||||
**
|
||||
** Description get registration control block by client interface.
|
||||
**
|
||||
** Returns pointer to the regcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_RCB *bta_gattc_cl_get_regcb(UINT8 client_if)
|
||||
{
|
||||
UINT8 i = 0;
|
||||
tBTA_GATTC_RCB *p_clrcb = &bta_gattc_cb.cl_rcb[0];
|
||||
|
||||
for (i = 0; i < BTA_GATTC_CL_MAX; i ++, p_clrcb ++) {
|
||||
if (p_clrcb->in_use &&
|
||||
p_clrcb->client_if == client_if) {
|
||||
return p_clrcb;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_num_reg_app
|
||||
**
|
||||
** Description find the number of registered application.
|
||||
**
|
||||
** Returns pointer to the regcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT8 bta_gattc_num_reg_app(void)
|
||||
{
|
||||
UINT8 i = 0, j = 0;
|
||||
|
||||
for (i = 0; i < BTA_GATTC_CL_MAX; i ++) {
|
||||
if (bta_gattc_cb.cl_rcb[i].in_use) {
|
||||
j ++;
|
||||
}
|
||||
}
|
||||
return j;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_find_clcb_by_cif
|
||||
**
|
||||
** Description get clcb by client interface and remote bd adddress
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_CLCB *bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda,
|
||||
tBTA_TRANSPORT transport)
|
||||
{
|
||||
tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++) {
|
||||
if (p_clcb->in_use &&
|
||||
p_clcb->p_rcb->client_if == client_if &&
|
||||
p_clcb->transport == transport &&
|
||||
bdcmp(p_clcb->bda, remote_bda) == 0) {
|
||||
return p_clcb;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_find_clcb_by_conn_id
|
||||
**
|
||||
** Description get clcb by connection ID
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_CLCB *bta_gattc_find_clcb_by_conn_id (UINT16 conn_id)
|
||||
{
|
||||
tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++) {
|
||||
if (p_clcb->in_use &&
|
||||
p_clcb->bta_conn_id == conn_id) {
|
||||
return p_clcb;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_clcb_alloc
|
||||
**
|
||||
** Description allocate CLCB
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_CLCB *bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
|
||||
tBTA_TRANSPORT transport)
|
||||
{
|
||||
UINT8 i_clcb = 0;
|
||||
tBTA_GATTC_CLCB *p_clcb = NULL;
|
||||
|
||||
for (i_clcb = 0; i_clcb < BTA_GATTC_CLCB_MAX; i_clcb++) {
|
||||
if (!bta_gattc_cb.clcb[i_clcb].in_use) {
|
||||
#if BTA_GATT_DEBUG == TRUE
|
||||
APPL_TRACE_DEBUG("bta_gattc_clcb_alloc: found clcb[%d] available", i_clcb);
|
||||
#endif
|
||||
p_clcb = &bta_gattc_cb.clcb[i_clcb];
|
||||
p_clcb->in_use = TRUE;
|
||||
p_clcb->status = BTA_GATT_OK;
|
||||
p_clcb->transport = transport;
|
||||
bdcpy(p_clcb->bda, remote_bda);
|
||||
|
||||
p_clcb->p_rcb = bta_gattc_cl_get_regcb(client_if);
|
||||
|
||||
if ((p_clcb->p_srcb = bta_gattc_find_srcb(remote_bda)) == NULL) {
|
||||
p_clcb->p_srcb = bta_gattc_srcb_alloc(remote_bda);
|
||||
}
|
||||
|
||||
if (p_clcb->p_rcb != NULL && p_clcb->p_srcb != NULL) {
|
||||
p_clcb->p_srcb->num_clcb ++;
|
||||
p_clcb->p_rcb->num_clcb ++;
|
||||
} else {
|
||||
/* release this clcb if clcb or srcb allocation failed */
|
||||
p_clcb->in_use = FALSE;
|
||||
p_clcb = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return p_clcb;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_find_alloc_clcb
|
||||
**
|
||||
** Description find or allocate CLCB if not found.
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_CLCB *bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
|
||||
tBTA_TRANSPORT transport)
|
||||
{
|
||||
tBTA_GATTC_CLCB *p_clcb ;
|
||||
|
||||
if ((p_clcb = bta_gattc_find_clcb_by_cif(client_if, remote_bda, transport)) == NULL) {
|
||||
p_clcb = bta_gattc_clcb_alloc(client_if, remote_bda, transport);
|
||||
}
|
||||
return p_clcb;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_clcb_dealloc
|
||||
**
|
||||
** Description Deallocte a clcb
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb)
|
||||
{
|
||||
tBTA_GATTC_SERV *p_srcb = NULL;
|
||||
|
||||
if (p_clcb) {
|
||||
p_srcb = p_clcb->p_srcb;
|
||||
if (p_srcb->num_clcb) {
|
||||
p_srcb->num_clcb --;
|
||||
}
|
||||
|
||||
if (p_clcb->p_rcb->num_clcb) {
|
||||
p_clcb->p_rcb->num_clcb --;
|
||||
}
|
||||
|
||||
/* if the srcb is no longer needed, reset the state */
|
||||
if ( p_srcb->num_clcb == 0) {
|
||||
p_srcb->connected = FALSE;
|
||||
p_srcb->state = BTA_GATTC_SERV_IDLE;
|
||||
p_srcb->mtu = 0;
|
||||
}
|
||||
|
||||
utl_freebuf((void **)&p_clcb->p_q_cmd);
|
||||
|
||||
memset(p_clcb, 0, sizeof(tBTA_GATTC_CLCB));
|
||||
} else {
|
||||
APPL_TRACE_ERROR("bta_gattc_clcb_dealloc p_clcb=NULL");
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_find_srcb
|
||||
**
|
||||
** Description find server cache by remote bd address currently in use
|
||||
**
|
||||
** Returns pointer to the server cache.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_SERV *bta_gattc_find_srcb(BD_ADDR bda)
|
||||
{
|
||||
tBTA_GATTC_SERV *p_srcb = &bta_gattc_cb.known_server[0];
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_srcb ++) {
|
||||
if (p_srcb->in_use && bdcmp(p_srcb->server_bda, bda) == 0) {
|
||||
return p_srcb;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_find_srvr_cache
|
||||
**
|
||||
** Description find server cache by remote bd address
|
||||
**
|
||||
** Returns pointer to the server cache.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_SERV *bta_gattc_find_srvr_cache(BD_ADDR bda)
|
||||
{
|
||||
tBTA_GATTC_SERV *p_srcb = &bta_gattc_cb.known_server[0];
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_srcb ++) {
|
||||
if (bdcmp(p_srcb->server_bda, bda) == 0) {
|
||||
return p_srcb;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_find_scb_by_cid
|
||||
**
|
||||
** Description find server control block by connection ID
|
||||
**
|
||||
** Returns pointer to the server cache.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_SERV *bta_gattc_find_scb_by_cid (UINT16 conn_id)
|
||||
{
|
||||
tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
|
||||
|
||||
if (p_clcb) {
|
||||
return p_clcb->p_srcb;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_srcb_alloc
|
||||
**
|
||||
** Description allocate server cache control block
|
||||
**
|
||||
** Returns pointer to the server cache.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_SERV *bta_gattc_srcb_alloc(BD_ADDR bda)
|
||||
{
|
||||
tBTA_GATTC_SERV *p_tcb = &bta_gattc_cb.known_server[0],
|
||||
*p_recycle = NULL;
|
||||
BOOLEAN found = FALSE;
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_tcb ++) {
|
||||
if (!p_tcb->in_use) {
|
||||
found = TRUE;
|
||||
break;
|
||||
} else if (!p_tcb->connected) {
|
||||
p_recycle = p_tcb;
|
||||
}
|
||||
}
|
||||
|
||||
/* if not found, try to recycle one known device */
|
||||
if (!found && !p_recycle) {
|
||||
p_tcb = NULL;
|
||||
} else if (!found && p_recycle) {
|
||||
p_tcb = p_recycle;
|
||||
}
|
||||
|
||||
if (p_tcb != NULL) {
|
||||
while (!GKI_queue_is_empty(&p_tcb->cache_buffer)) {
|
||||
GKI_freebuf (GKI_dequeue (&p_tcb->cache_buffer));
|
||||
}
|
||||
|
||||
utl_freebuf((void **)&p_tcb->p_srvc_list);
|
||||
memset(p_tcb, 0 , sizeof(tBTA_GATTC_SERV));
|
||||
|
||||
p_tcb->in_use = TRUE;
|
||||
bdcpy(p_tcb->server_bda, bda);
|
||||
}
|
||||
return p_tcb;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_enqueue
|
||||
**
|
||||
** Description enqueue a client request in clcb.
|
||||
**
|
||||
** Returns success or failure.
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
|
||||
{
|
||||
|
||||
if (p_clcb->p_q_cmd == NULL) {
|
||||
p_clcb->p_q_cmd = p_data;
|
||||
} else {
|
||||
APPL_TRACE_ERROR("already has a pending command!!");
|
||||
/* skip the callback now. ----- need to send callback ? */
|
||||
}
|
||||
return (p_clcb->p_q_cmd != NULL) ? TRUE : FALSE;
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_pack_attr_uuid
|
||||
**
|
||||
** Description pack UUID into a stream.
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gattc_pack_attr_uuid(tBTA_GATTC_CACHE_ATTR *p_attr, tBT_UUID *p_uuid)
|
||||
{
|
||||
UINT8 *pp = (UINT8 *)p_attr->p_uuid;
|
||||
|
||||
memset(p_uuid, 0, sizeof(tBT_UUID));
|
||||
|
||||
p_uuid->len = p_attr->uuid_len;
|
||||
|
||||
if (p_attr->uuid_len == LEN_UUID_16) {
|
||||
STREAM_TO_UINT16(p_uuid->uu.uuid16, pp);
|
||||
} else {
|
||||
memcpy(p_uuid->uu.uuid128, pp, LEN_UUID_128);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_cpygattid
|
||||
**
|
||||
** Description copy two tBTA_GATT_ID value
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gattc_cpygattid(tBTA_GATT_ID *p_des, tBTA_GATT_ID *p_src)
|
||||
{
|
||||
memset ((void *)p_des, 0, sizeof(tBTA_GATT_ID));
|
||||
|
||||
p_des->inst_id = p_src->inst_id;
|
||||
|
||||
p_des->uuid.len = p_src->uuid.len;
|
||||
|
||||
if (p_des->uuid.len == LEN_UUID_16) {
|
||||
p_des->uuid.uu.uuid16 = p_src->uuid.uu.uuid16;
|
||||
} else if (p_des->uuid.len == LEN_UUID_128) {
|
||||
memcpy(p_des->uuid.uu.uuid128, p_src->uuid.uu.uuid128, LEN_UUID_128);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_gattid_compare
|
||||
**
|
||||
** Description compare two tBTA_GATT_ID type of pointer
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_gattid_compare(tBTA_GATT_ID *p_src, tBTA_GATT_ID *p_tar)
|
||||
{
|
||||
if (p_src->inst_id == p_tar->inst_id &&
|
||||
bta_gattc_uuid_compare (&p_src->uuid, &p_tar->uuid, TRUE )) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_srvcid_compare
|
||||
**
|
||||
** Description compare two tBTA_GATT_SRVC_ID type of pointer
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_srvcid_compare(tBTA_GATT_SRVC_ID *p_src, tBTA_GATT_SRVC_ID *p_tar)
|
||||
{
|
||||
if (p_src->is_primary == p_tar->is_primary &&
|
||||
bta_gattc_gattid_compare (&p_src->id, &p_tar->id)) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_charid_compare
|
||||
**
|
||||
** Description compare two tBTA_GATTC_CHAR_ID type of pointer
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_charid_compare(tBTA_GATTC_CHAR_ID *p_src, tBTA_GATTC_CHAR_ID *p_tar)
|
||||
{
|
||||
if (bta_gattc_gattid_compare (&p_src->char_id, &p_tar->char_id) &&
|
||||
bta_gattc_srvcid_compare (&p_src->srvc_id, &p_tar->srvc_id)) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_check_notif_registry
|
||||
**
|
||||
** Description check if the service notificaition has been registered.
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_check_notif_registry(tBTA_GATTC_RCB *p_clreg, tBTA_GATTC_SERV *p_srcb,
|
||||
tBTA_GATTC_NOTIFY *p_notify)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++) {
|
||||
if (p_clreg->notif_reg[i].in_use &&
|
||||
bdcmp(p_clreg->notif_reg[i].remote_bda, p_srcb->server_bda) == 0 &&
|
||||
bta_gattc_charid_compare (&p_clreg->notif_reg[i].char_id, &p_notify->char_id)) {
|
||||
APPL_TRACE_DEBUG("Notification registered!");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_clear_notif_registration
|
||||
**
|
||||
** Description clear up the notification registration information by BD_ADDR.
|
||||
**
|
||||
** Returns None.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gattc_clear_notif_registration(UINT16 conn_id)
|
||||
{
|
||||
BD_ADDR remote_bda;
|
||||
tBTA_GATTC_IF gatt_if;
|
||||
tBTA_GATTC_RCB *p_clrcb ;
|
||||
UINT8 i;
|
||||
tGATT_TRANSPORT transport;
|
||||
|
||||
if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) {
|
||||
if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) != NULL) {
|
||||
for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++) {
|
||||
if (p_clrcb->notif_reg[i].in_use &&
|
||||
!bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda)) {
|
||||
memset(&p_clrcb->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_ERROR("can not clear indication/notif registration for unknown app");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_pack_cb_data
|
||||
**
|
||||
** Description pack the data from read response into callback data structure.
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATT_STATUS bta_gattc_pack_read_cb_data(tBTA_GATTC_SERV *p_srcb,
|
||||
tBT_UUID *p_descr_uuid,
|
||||
tGATT_VALUE *p_attr,
|
||||
tBTA_GATT_READ_VAL *p_value)
|
||||
{
|
||||
UINT8 i = 0, *pp = p_attr->value;
|
||||
tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_CHAR_AGG_FORMAT}};
|
||||
UINT16 handle;
|
||||
tBTA_GATT_STATUS status = BTA_GATT_OK;
|
||||
|
||||
/* GATT_UUID_CHAR_AGG_FORMAT */
|
||||
if (bta_gattc_uuid_compare (&uuid, p_descr_uuid, TRUE)) {
|
||||
while (p_attr->len >= 2 && i < BTA_GATTC_MULTI_MAX) {
|
||||
STREAM_TO_UINT16(handle, pp);
|
||||
|
||||
if (bta_gattc_handle2id(p_srcb,
|
||||
handle,
|
||||
&p_value->aggre_value.pre_format[i].char_id.srvc_id,
|
||||
&p_value->aggre_value.pre_format[i].char_id.char_id,
|
||||
&p_value->aggre_value.pre_format[i].descr_id) == FALSE) {
|
||||
status = BTA_GATT_INTERNAL_ERROR;
|
||||
APPL_TRACE_ERROR("can not map to GATT ID. handle = 0x%04x", handle);
|
||||
break;
|
||||
}
|
||||
i ++;
|
||||
p_attr->len -= 2;
|
||||
}
|
||||
p_value->aggre_value.num_pres_fmt = i;
|
||||
} else {
|
||||
/* all others, take as raw format */
|
||||
p_value->unformat.len = p_attr->len;
|
||||
p_value->unformat.p_value = p_attr->value;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_mark_bg_conn
|
||||
**
|
||||
** Description mark background connection status when a bg connection is initiated
|
||||
** or terminated.
|
||||
**
|
||||
** Returns TRUE if success; FALSE otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_mark_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR_PTR remote_bda_ptr,
|
||||
BOOLEAN add, BOOLEAN is_listen)
|
||||
{
|
||||
tBTA_GATTC_BG_TCK *p_bg_tck = &bta_gattc_cb.bg_track[0];
|
||||
UINT8 i = 0;
|
||||
tBTA_GATTC_CIF_MASK *p_cif_mask;
|
||||
|
||||
for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_bg_tck ++) {
|
||||
if (p_bg_tck->in_use &&
|
||||
((remote_bda_ptr != NULL && bdcmp(p_bg_tck->remote_bda, remote_bda_ptr) == 0) ||
|
||||
(remote_bda_ptr == NULL && bdcmp(p_bg_tck->remote_bda, dummy_bda) == 0))) {
|
||||
p_cif_mask = is_listen ? &p_bg_tck->cif_adv_mask : &p_bg_tck->cif_mask;
|
||||
|
||||
if (add)
|
||||
/* mask on the cif bit */
|
||||
{
|
||||
*p_cif_mask |= (1 << (client_if - 1));
|
||||
} else {
|
||||
if (client_if != 0) {
|
||||
*p_cif_mask &= (~(1 << (client_if - 1)));
|
||||
} else {
|
||||
*p_cif_mask = 0;
|
||||
}
|
||||
}
|
||||
/* no BG connection for this device, make it available */
|
||||
if (p_bg_tck->cif_mask == 0 && p_bg_tck->cif_adv_mask == 0) {
|
||||
memset(p_bg_tck, 0, sizeof(tBTA_GATTC_BG_TCK));
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
if (!add) {
|
||||
if (remote_bda_ptr) {
|
||||
// bdstr_t bdstr = {0};
|
||||
char bdstr[18] = {0};
|
||||
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)));
|
||||
}
|
||||
return FALSE;
|
||||
} else { /* adding a new device mask */
|
||||
for (i = 0, p_bg_tck = &bta_gattc_cb.bg_track[0];
|
||||
i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_bg_tck ++) {
|
||||
if (!p_bg_tck->in_use) {
|
||||
p_bg_tck->in_use = TRUE;
|
||||
if (remote_bda_ptr) {
|
||||
bdcpy(p_bg_tck->remote_bda, remote_bda_ptr);
|
||||
} else {
|
||||
bdcpy(p_bg_tck->remote_bda, dummy_bda);
|
||||
}
|
||||
|
||||
p_cif_mask = is_listen ? &p_bg_tck->cif_adv_mask : &p_bg_tck->cif_mask;
|
||||
|
||||
*p_cif_mask = (1 << (client_if - 1));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
APPL_TRACE_ERROR("no available space to mark the bg connection status");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_check_bg_conn
|
||||
**
|
||||
** Description check if this is a background connection background connection.
|
||||
**
|
||||
** Returns TRUE if success; FALSE otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_check_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR remote_bda, UINT8 role)
|
||||
{
|
||||
tBTA_GATTC_BG_TCK *p_bg_tck = &bta_gattc_cb.bg_track[0];
|
||||
UINT8 i = 0;
|
||||
BOOLEAN is_bg_conn = FALSE;
|
||||
|
||||
for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX && !is_bg_conn; i ++, p_bg_tck ++) {
|
||||
if (p_bg_tck->in_use &&
|
||||
(bdcmp(p_bg_tck->remote_bda, remote_bda) == 0 ||
|
||||
bdcmp(p_bg_tck->remote_bda, dummy_bda) == 0)) {
|
||||
if (((p_bg_tck->cif_mask & (1 << (client_if - 1))) != 0) &&
|
||||
role == HCI_ROLE_MASTER) {
|
||||
is_bg_conn = TRUE;
|
||||
}
|
||||
|
||||
if (((p_bg_tck->cif_adv_mask & (1 << (client_if - 1))) != 0) &&
|
||||
role == HCI_ROLE_SLAVE) {
|
||||
is_bg_conn = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return is_bg_conn;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_send_open_cback
|
||||
**
|
||||
** Description send open callback
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status,
|
||||
BD_ADDR remote_bda, UINT16 conn_id,
|
||||
tBTA_TRANSPORT transport, UINT16 mtu)
|
||||
{
|
||||
tBTA_GATTC cb_data;
|
||||
|
||||
if (p_clreg->p_cback) {
|
||||
memset(&cb_data, 0, sizeof(tBTA_GATTC));
|
||||
|
||||
cb_data.open.status = status;
|
||||
cb_data.open.client_if = p_clreg->client_if;
|
||||
cb_data.open.conn_id = conn_id;
|
||||
cb_data.open.mtu = mtu;
|
||||
cb_data.open.transport = transport;
|
||||
bdcpy(cb_data.open.remote_bda, remote_bda);
|
||||
|
||||
(*p_clreg->p_cback)(BTA_GATTC_OPEN_EVT, &cb_data);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_conn_alloc
|
||||
**
|
||||
** Description allocate connection tracking spot
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_CONN *bta_gattc_conn_alloc(BD_ADDR remote_bda)
|
||||
{
|
||||
UINT8 i_conn = 0;
|
||||
tBTA_GATTC_CONN *p_conn = &bta_gattc_cb.conn_track[0];
|
||||
|
||||
for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++) {
|
||||
if (!p_conn->in_use) {
|
||||
#if BTA_GATT_DEBUG == TRUE
|
||||
APPL_TRACE_DEBUG("bta_gattc_conn_alloc: found conn_track[%d] available", i_conn);
|
||||
#endif
|
||||
p_conn->in_use = TRUE;
|
||||
bdcpy(p_conn->remote_bda, remote_bda);
|
||||
return p_conn;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_conn_find
|
||||
**
|
||||
** Description allocate connection tracking spot
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_CONN *bta_gattc_conn_find(BD_ADDR remote_bda)
|
||||
{
|
||||
UINT8 i_conn = 0;
|
||||
tBTA_GATTC_CONN *p_conn = &bta_gattc_cb.conn_track[0];
|
||||
|
||||
for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++) {
|
||||
if (p_conn->in_use && bdcmp(remote_bda, p_conn->remote_bda) == 0) {
|
||||
#if BTA_GATT_DEBUG == TRUE
|
||||
APPL_TRACE_DEBUG("bta_gattc_conn_find: found conn_track[%d] matched", i_conn);
|
||||
#endif
|
||||
return p_conn;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_conn_find_alloc
|
||||
**
|
||||
** Description find or allocate connection tracking spot
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_CONN *bta_gattc_conn_find_alloc(BD_ADDR remote_bda)
|
||||
{
|
||||
tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find (remote_bda);
|
||||
|
||||
if (p_conn == NULL) {
|
||||
p_conn = bta_gattc_conn_alloc(remote_bda);
|
||||
}
|
||||
return p_conn;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_conn_dealloc
|
||||
**
|
||||
** Description de-allocate connection tracking spot
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_conn_dealloc(BD_ADDR remote_bda)
|
||||
{
|
||||
tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find (remote_bda);
|
||||
|
||||
if (p_conn != NULL) {
|
||||
p_conn->in_use = FALSE;
|
||||
memset(p_conn->remote_bda, 0, BD_ADDR_LEN);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_find_int_conn_clcb
|
||||
**
|
||||
** Description try to locate a clcb when an internal connecion event arrives.
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_CLCB *bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTC_CLCB *p_clcb = NULL;
|
||||
|
||||
if (p_msg->int_conn.role == HCI_ROLE_SLAVE) {
|
||||
bta_gattc_conn_find_alloc(p_msg->int_conn.remote_bda);
|
||||
}
|
||||
|
||||
/* try to locate a logic channel */
|
||||
if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
|
||||
p_msg->int_conn.remote_bda,
|
||||
p_msg->int_conn.transport)) == NULL) {
|
||||
/* for a background connection or listening connection */
|
||||
if (/*p_msg->int_conn.role == HCI_ROLE_SLAVE || */
|
||||
bta_gattc_check_bg_conn(p_msg->int_conn.client_if,
|
||||
p_msg->int_conn.remote_bda,
|
||||
p_msg->int_conn.role)) {
|
||||
/* allocate a new channel */
|
||||
p_clcb = bta_gattc_clcb_alloc(p_msg->int_conn.client_if,
|
||||
p_msg->int_conn.remote_bda,
|
||||
p_msg->int_conn.transport);
|
||||
}
|
||||
}
|
||||
return p_clcb;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_find_int_disconn_clcb
|
||||
**
|
||||
** Description try to locate a clcb when an internal disconnect callback arrives.
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_CLCB *bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTC_CLCB *p_clcb = NULL;
|
||||
|
||||
bta_gattc_conn_dealloc(p_msg->int_conn.remote_bda);
|
||||
if ((p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->int_conn.hdr.layer_specific)) == NULL) {
|
||||
/* connection attempt failed, send connection callback event */
|
||||
p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
|
||||
p_msg->int_conn.remote_bda,
|
||||
p_msg->int_conn.transport);
|
||||
}
|
||||
if (p_clcb == NULL) {
|
||||
APPL_TRACE_DEBUG(" disconnection ID: [%d] not used by BTA",
|
||||
p_msg->int_conn.hdr.layer_specific);
|
||||
}
|
||||
return p_clcb;
|
||||
}
|
||||
|
||||
#endif /* BTA_GATT_INCLUDED */
|
||||
966
components/bt/bluedroid/bta/gatt/bta_gatts_act.c
Normal file
966
components/bt/bluedroid/bta/gatt/bta_gatts_act.c
Normal file
@@ -0,0 +1,966 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the GATT Server action functions for the state
|
||||
* machine.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#include "bt_target.h"
|
||||
|
||||
#if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
|
||||
|
||||
#include "utl.h"
|
||||
#include "gki.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_gatts_int.h"
|
||||
#include "bta_gatts_co.h"
|
||||
#include "btm_ble_api.h"
|
||||
#include <string.h>
|
||||
|
||||
static void bta_gatts_nv_save_cback(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range);
|
||||
static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req,
|
||||
tGATTS_SRV_CHG_RSP *p_rsp);
|
||||
|
||||
static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
|
||||
BOOLEAN connected, tGATT_DISCONN_REASON reason,
|
||||
tGATT_TRANSPORT transport);
|
||||
static void bta_gatts_send_request_cback (UINT16 conn_id,
|
||||
UINT32 trans_id,
|
||||
tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data);
|
||||
static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested);
|
||||
|
||||
static tGATT_CBACK bta_gatts_cback = {
|
||||
bta_gatts_conn_cback,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
bta_gatts_send_request_cback,
|
||||
NULL,
|
||||
bta_gatts_cong_cback
|
||||
};
|
||||
|
||||
tGATT_APPL_INFO bta_gatts_nv_cback = {
|
||||
bta_gatts_nv_save_cback,
|
||||
bta_gatts_nv_srv_chg_cback
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_nv_save_cback
|
||||
**
|
||||
** Description NV save callback function.
|
||||
**
|
||||
** Parameter is_add: true is to add a handle range; otherwise is to delete.
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_gatts_nv_save_cback(BOOLEAN is_add, tGATTS_HNDL_RANGE *p_hndl_range)
|
||||
{
|
||||
bta_gatts_co_update_handle_range(is_add, (tBTA_GATTS_HNDL_RANGE *)p_hndl_range);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_nv_srv_chg_cback
|
||||
**
|
||||
** Description NV save callback function.
|
||||
**
|
||||
** Parameter is_add: true is to add a handle range; otherwise is to delete.
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd,
|
||||
tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp)
|
||||
{
|
||||
return bta_gatts_co_srv_chg((tBTA_GATTS_SRV_CHG_CMD) cmd,
|
||||
(tBTA_GATTS_SRV_CHG_REQ *) p_req,
|
||||
(tBTA_GATTS_SRV_CHG_RSP *) p_rsp);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_enable
|
||||
**
|
||||
** Description enable BTA GATTS module.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_enable(tBTA_GATTS_CB *p_cb)
|
||||
{
|
||||
UINT8 index = 0;
|
||||
tBTA_GATTS_HNDL_RANGE handle_range;
|
||||
|
||||
if (p_cb->enabled) {
|
||||
APPL_TRACE_DEBUG("GATTS already enabled.");
|
||||
} else {
|
||||
memset(p_cb, 0, sizeof(tBTA_GATTS_CB));
|
||||
|
||||
p_cb->enabled = TRUE;
|
||||
|
||||
while ( bta_gatts_co_load_handle_range(index, &handle_range)) {
|
||||
GATTS_AddHandleRange((tGATTS_HNDL_RANGE *)&handle_range);
|
||||
memset(&handle_range, 0, sizeof(tGATTS_HNDL_RANGE));
|
||||
index++;
|
||||
}
|
||||
|
||||
APPL_TRACE_DEBUG("bta_gatts_enable: num of handle range added=%d", index);
|
||||
|
||||
if (!GATTS_NVRegister(&bta_gatts_nv_cback)) {
|
||||
APPL_TRACE_ERROR("BTA GATTS NV register failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_api_disable
|
||||
**
|
||||
** Description disable BTA GATTS module.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_api_disable(tBTA_GATTS_CB *p_cb)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
if (p_cb->enabled) {
|
||||
for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++) {
|
||||
if (p_cb->rcb[i].in_use) {
|
||||
GATT_Deregister(p_cb->rcb[i].gatt_if);
|
||||
}
|
||||
}
|
||||
memset(p_cb, 0, sizeof(tBTA_GATTS_CB));
|
||||
} else {
|
||||
APPL_TRACE_ERROR("GATTS not enabled");
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_register
|
||||
**
|
||||
** Description register an application.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_register(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_INT_START_IF *p_buf;
|
||||
tBTA_GATTS cb_data;
|
||||
tBTA_GATT_STATUS status = BTA_GATT_OK;
|
||||
UINT8 i, first_unuse = 0xff;
|
||||
|
||||
if (p_cb->enabled == FALSE) {
|
||||
bta_gatts_enable(p_cb);
|
||||
}
|
||||
|
||||
for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++) {
|
||||
if (p_cb->rcb[i].in_use) {
|
||||
if (bta_gatts_uuid_compare(p_cb->rcb[i].app_uuid, p_msg->api_reg.app_uuid)) {
|
||||
APPL_TRACE_ERROR("application already registered.\n");
|
||||
status = BTA_GATT_DUP_REG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (status == BTA_GATT_OK) {
|
||||
for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++) {
|
||||
if (first_unuse == 0xff && !p_cb->rcb[i].in_use) {
|
||||
first_unuse = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cb_data.reg_oper.server_if = BTA_GATTS_INVALID_IF;
|
||||
// btla-specific ++
|
||||
memcpy(&cb_data.reg_oper.uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
|
||||
// btla-specific --
|
||||
if (first_unuse != 0xff) {
|
||||
APPL_TRACE_VERBOSE("register application first_unuse rcb_idx = %d", first_unuse);
|
||||
|
||||
p_cb->rcb[first_unuse].in_use = TRUE;
|
||||
p_cb->rcb[first_unuse].p_cback = p_msg->api_reg.p_cback;
|
||||
memcpy(&p_cb->rcb[first_unuse].app_uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
|
||||
cb_data.reg_oper.server_if =
|
||||
p_cb->rcb[first_unuse].gatt_if =
|
||||
GATT_Register(&p_msg->api_reg.app_uuid, &bta_gatts_cback);
|
||||
if ( !p_cb->rcb[first_unuse].gatt_if) {
|
||||
status = BTA_GATT_NO_RESOURCES;
|
||||
} else {
|
||||
if ((p_buf =
|
||||
(tBTA_GATTS_INT_START_IF *) GKI_getbuf(sizeof(tBTA_GATTS_INT_START_IF))) != NULL) {
|
||||
p_buf->hdr.event = BTA_GATTS_INT_START_IF_EVT;
|
||||
p_buf->server_if = p_cb->rcb[first_unuse].gatt_if;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
} else {
|
||||
status = BTA_GATT_NO_RESOURCES;
|
||||
memset( &p_cb->rcb[first_unuse], 0 , sizeof(tBTA_GATTS_RCB));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
status = BTA_GATT_NO_RESOURCES;
|
||||
}
|
||||
|
||||
}
|
||||
cb_data.reg_oper.status = status;
|
||||
if (p_msg->api_reg.p_cback) {
|
||||
(*p_msg->api_reg.p_cback)(BTA_GATTS_REG_EVT, &cb_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_start_if
|
||||
**
|
||||
** Description start an application interface.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_start_if(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
UNUSED(p_cb);
|
||||
|
||||
if (bta_gatts_find_app_rcb_by_app_if(p_msg->int_start_if.server_if)) {
|
||||
GATT_StartIf(p_msg->int_start_if.server_if);
|
||||
} else {
|
||||
APPL_TRACE_ERROR("Unable to start app.: Unknown interface =%d",
|
||||
p_msg->int_start_if.server_if );
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_deregister
|
||||
**
|
||||
** Description deregister an application.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_deregister(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATT_STATUS status = BTA_GATT_ERROR;
|
||||
tBTA_GATTS_CBACK *p_cback = NULL;
|
||||
UINT8 i;
|
||||
tBTA_GATTS cb_data;
|
||||
|
||||
cb_data.reg_oper.server_if = p_msg->api_dereg.server_if;
|
||||
cb_data.reg_oper.status = status;
|
||||
|
||||
for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++) {
|
||||
if (p_cb->rcb[i].in_use && p_cb->rcb[i].gatt_if == p_msg->api_dereg.server_if) {
|
||||
p_cback = p_cb->rcb[i].p_cback;
|
||||
status = BTA_GATT_OK;
|
||||
|
||||
/* deregister the app */
|
||||
GATT_Deregister(p_cb->rcb[i].gatt_if);
|
||||
|
||||
/* reset cb */
|
||||
memset(&p_cb->rcb[i], 0, sizeof(tBTA_GATTS_RCB));
|
||||
cb_data.reg_oper.status = status;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_cback) {
|
||||
(*p_cback)(BTA_GATTS_DEREG_EVT, &cb_data);
|
||||
} else {
|
||||
APPL_TRACE_ERROR("application not registered.");
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_create_srvc
|
||||
**
|
||||
** Description action function to create a service.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_create_srvc(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
UINT8 rcb_idx;
|
||||
tBTA_GATTS cb_data;
|
||||
UINT8 srvc_idx;
|
||||
UINT16 service_id = 0;
|
||||
|
||||
cb_data.create.status = BTA_GATT_ERROR;
|
||||
|
||||
rcb_idx = bta_gatts_find_app_rcb_idx_by_app_if(p_cb, p_msg->api_create_svc.server_if);
|
||||
|
||||
APPL_TRACE_DEBUG("create service rcb_idx = %d", rcb_idx);
|
||||
|
||||
if (rcb_idx != BTA_GATTS_INVALID_APP) {
|
||||
if ((srvc_idx = bta_gatts_alloc_srvc_cb(p_cb, rcb_idx)) != BTA_GATTS_INVALID_APP) {
|
||||
/* create the service now */
|
||||
service_id = GATTS_CreateService (p_cb->rcb[rcb_idx].gatt_if,
|
||||
&p_msg->api_create_svc.service_uuid,
|
||||
p_msg->api_create_svc.inst,
|
||||
p_msg->api_create_svc.num_handle,
|
||||
p_msg->api_create_svc.is_pri);
|
||||
|
||||
if (service_id != 0) {
|
||||
memcpy(&p_cb->srvc_cb[srvc_idx].service_uuid,
|
||||
&p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
|
||||
p_cb->srvc_cb[srvc_idx].service_id = service_id;
|
||||
p_cb->srvc_cb[srvc_idx].inst_num = p_msg->api_create_svc.inst;
|
||||
p_cb->srvc_cb[srvc_idx].idx = srvc_idx;
|
||||
|
||||
cb_data.create.status = BTA_GATT_OK;
|
||||
cb_data.create.service_id = service_id;
|
||||
// btla-specific ++
|
||||
cb_data.create.is_primary = p_msg->api_create_svc.is_pri;
|
||||
// btla-specific --
|
||||
cb_data.create.server_if = p_cb->rcb[rcb_idx].gatt_if;
|
||||
} else {
|
||||
cb_data.status = BTA_GATT_ERROR;
|
||||
memset(&p_cb->srvc_cb[srvc_idx], 0, sizeof(tBTA_GATTS_SRVC_CB));
|
||||
APPL_TRACE_ERROR("service creation failed.");
|
||||
}
|
||||
// btla-specific ++
|
||||
memcpy(&cb_data.create.uuid, &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
|
||||
cb_data.create.svc_instance = p_msg->api_create_svc.inst;
|
||||
// btla-specific --
|
||||
}
|
||||
if (p_cb->rcb[rcb_idx].p_cback) {
|
||||
(* p_cb->rcb[rcb_idx].p_cback)(BTA_GATTS_CREATE_EVT, &cb_data);
|
||||
}
|
||||
} else { /* application not registered */
|
||||
APPL_TRACE_ERROR("Application not registered");
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_add_include_srvc
|
||||
**
|
||||
** Description action function to add an included service.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_add_include_srvc(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
|
||||
UINT16 attr_id = 0;
|
||||
tBTA_GATTS cb_data;
|
||||
|
||||
attr_id = GATTS_AddIncludeService(p_msg->api_add_incl_srvc.hdr.layer_specific,
|
||||
p_msg->api_add_incl_srvc.included_service_id);
|
||||
|
||||
cb_data.add_result.server_if = p_rcb->gatt_if;
|
||||
cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
|
||||
cb_data.add_result.attr_id = attr_id;
|
||||
|
||||
if (attr_id) {
|
||||
cb_data.add_result.status = BTA_GATT_OK;
|
||||
} else {
|
||||
cb_data.add_result.status = BTA_GATT_ERROR;
|
||||
}
|
||||
|
||||
if (p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_ADD_INCL_SRVC_EVT, &cb_data);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_add_char
|
||||
**
|
||||
** Description action function to add characteristic.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
|
||||
UINT16 attr_id = 0;
|
||||
tBTA_GATTS cb_data;
|
||||
|
||||
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){
|
||||
p_attr_val = &p_msg->api_add_char.attr_val;
|
||||
}
|
||||
|
||||
if(p_msg->api_add_char.control.auto_rsp != 0){
|
||||
p_control = &p_msg->api_add_char.control;
|
||||
}
|
||||
|
||||
|
||||
attr_id = GATTS_AddCharacteristic(p_msg->api_add_char.hdr.layer_specific,
|
||||
&p_msg->api_add_char.char_uuid,
|
||||
p_msg->api_add_char.perm,
|
||||
p_msg->api_add_char.property, p_attr_val, p_control);
|
||||
cb_data.add_result.server_if = p_rcb->gatt_if;
|
||||
cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
|
||||
cb_data.add_result.attr_id = attr_id;
|
||||
// btla-specific ++
|
||||
memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char.char_uuid, sizeof(tBT_UUID));
|
||||
// btla-specific --
|
||||
|
||||
if (attr_id) {
|
||||
cb_data.add_result.status = BTA_GATT_OK;
|
||||
} else {
|
||||
cb_data.add_result.status = BTA_GATT_ERROR;
|
||||
}
|
||||
if((p_attr_val != NULL) && (p_attr_val->attr_val != NULL)){
|
||||
GKI_freebuf(p_attr_val->attr_val);
|
||||
}
|
||||
|
||||
if (p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_EVT, &cb_data);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_add_char_descr
|
||||
**
|
||||
** Description action function to add characteristic descriptor.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
|
||||
UINT16 attr_id = 0;
|
||||
tBTA_GATTS cb_data;
|
||||
tGATT_ATTR_VAL *p_attr_val = NULL;
|
||||
tGATTS_ATTR_CONTROL *p_control = NULL;
|
||||
|
||||
if (p_msg->api_add_char_descr.attr_val.attr_max_len != 0) {
|
||||
p_attr_val = &p_msg->api_add_char_descr.attr_val;
|
||||
}
|
||||
|
||||
if (p_msg->api_add_char_descr.control.auto_rsp != 0) {
|
||||
p_control = &p_msg->api_add_char_descr.control;
|
||||
}
|
||||
attr_id = GATTS_AddCharDescriptor(p_msg->api_add_char_descr.hdr.layer_specific,
|
||||
p_msg->api_add_char_descr.perm,
|
||||
&p_msg->api_add_char_descr.descr_uuid, p_attr_val,
|
||||
p_control);
|
||||
|
||||
cb_data.add_result.server_if = p_rcb->gatt_if;
|
||||
cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
|
||||
cb_data.add_result.attr_id = attr_id;
|
||||
// btla-specific ++
|
||||
memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char_descr.descr_uuid, sizeof(tBT_UUID));
|
||||
// btla-specific --
|
||||
|
||||
if (attr_id) {
|
||||
cb_data.add_result.status = BTA_GATT_OK;
|
||||
} else {
|
||||
cb_data.add_result.status = BTA_GATT_ERROR;
|
||||
}
|
||||
if((p_attr_val != NULL) && (p_attr_val->attr_val != NULL)){
|
||||
GKI_freebuf(p_attr_val->attr_val);
|
||||
}
|
||||
|
||||
if (p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_DESCR_EVT, &cb_data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_add_char_descr
|
||||
**
|
||||
** Description action function to add characteristic descriptor.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_set_attr_value(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
|
||||
UINT16 attr_id = 0;
|
||||
tBTA_GATTS cb_data;
|
||||
tBTA_GATT_STATUS gatts_status;
|
||||
gatts_status = GATTS_SetAttributeValue(p_msg->api_add_char_descr.hdr.layer_specific,
|
||||
p_msg->api_set_val.length,
|
||||
p_msg->api_set_val.value);
|
||||
|
||||
cb_data.attr_val.server_if = p_rcb->gatt_if;
|
||||
cb_data.attr_val.service_id = p_msg->api_set_val.hdr.layer_specific;
|
||||
cb_data.attr_val.attr_id = attr_id;
|
||||
cb_data.attr_val.status = gatts_status;
|
||||
|
||||
if (p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_SET_ATTR_VAL_EVT, &cb_data);
|
||||
}
|
||||
}
|
||||
|
||||
void bta_gatts_get_attr_value(UINT16 attr_handle, UINT16 *length, UINT8 **value)
|
||||
{
|
||||
GATTS_GetAttributeValue(attr_handle, length, value);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_delete_service
|
||||
**
|
||||
** Description action function to delete a service.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
|
||||
tBTA_GATTS cb_data;
|
||||
|
||||
cb_data.srvc_oper.server_if = p_rcb->gatt_if;
|
||||
cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
|
||||
|
||||
if (GATTS_DeleteService(p_rcb->gatt_if,
|
||||
&p_srvc_cb->service_uuid,
|
||||
p_srvc_cb->inst_num)) {
|
||||
cb_data.srvc_oper.status = BTA_GATT_OK;
|
||||
memset(p_srvc_cb, 0, sizeof(tBTA_GATTS_SRVC_CB));
|
||||
} else {
|
||||
cb_data.srvc_oper.status = BTA_GATT_ERROR;
|
||||
}
|
||||
|
||||
if (p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_DELELTE_EVT, &cb_data);
|
||||
}
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_start_service
|
||||
**
|
||||
** Description action function to start a service.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_start_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
|
||||
tBTA_GATTS cb_data;
|
||||
|
||||
cb_data.srvc_oper.server_if = p_rcb->gatt_if;
|
||||
cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
|
||||
|
||||
if (GATTS_StartService(p_rcb->gatt_if,
|
||||
p_srvc_cb->service_id,
|
||||
p_msg->api_start.transport) == GATT_SUCCESS) {
|
||||
APPL_TRACE_DEBUG("bta_gatts_start_service service_id= %d", p_srvc_cb->service_id);
|
||||
cb_data.srvc_oper.status = BTA_GATT_OK;
|
||||
} else {
|
||||
cb_data.srvc_oper.status = BTA_GATT_ERROR;
|
||||
}
|
||||
|
||||
if (p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_START_EVT, &cb_data);
|
||||
}
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_stop_service
|
||||
**
|
||||
** Description action function to stop a service.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
|
||||
tBTA_GATTS cb_data;
|
||||
UNUSED(p_msg);
|
||||
|
||||
GATTS_StopService(p_srvc_cb->service_id);
|
||||
cb_data.srvc_oper.server_if = p_rcb->gatt_if;
|
||||
cb_data.srvc_oper.service_id = p_srvc_cb->service_id;
|
||||
cb_data.srvc_oper.status = BTA_GATT_OK;
|
||||
APPL_TRACE_ERROR("bta_gatts_stop_service service_id= %d", p_srvc_cb->service_id);
|
||||
|
||||
if (p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_STOP_EVT, &cb_data);
|
||||
}
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_send_rsp
|
||||
**
|
||||
** Description GATTS send response.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_send_rsp (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
UNUSED(p_cb);
|
||||
|
||||
if (GATTS_SendRsp (p_msg->api_rsp.hdr.layer_specific,
|
||||
p_msg->api_rsp.trans_id,
|
||||
p_msg->api_rsp.status,
|
||||
(tGATTS_RSP *)p_msg->api_rsp.p_rsp) != GATT_SUCCESS) {
|
||||
APPL_TRACE_ERROR("Sending response failed\n");
|
||||
}
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_indicate_handle
|
||||
**
|
||||
** Description GATTS send handle value indication or notification.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_SRVC_CB *p_srvc_cb;
|
||||
tBTA_GATTS_RCB *p_rcb = NULL;
|
||||
tBTA_GATT_STATUS status = BTA_GATT_ILLEGAL_PARAMETER;
|
||||
tGATT_IF gatt_if;
|
||||
BD_ADDR remote_bda;
|
||||
tBTA_TRANSPORT transport;
|
||||
tBTA_GATTS cb_data;
|
||||
|
||||
p_srvc_cb = bta_gatts_find_srvc_cb_by_attr_id (p_cb, p_msg->api_indicate.attr_id);
|
||||
|
||||
if (p_srvc_cb ) {
|
||||
if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific,
|
||||
&gatt_if, remote_bda, &transport)) {
|
||||
p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
|
||||
|
||||
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
|
||||
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) {
|
||||
bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
|
||||
bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_ERROR("Unknown connection ID: %d fail sending notification",
|
||||
p_msg->api_indicate.hdr.layer_specific);
|
||||
}
|
||||
|
||||
if ((status != GATT_SUCCESS || !p_msg->api_indicate.need_confirm) &&
|
||||
p_rcb && p_cb->rcb[p_srvc_cb->rcb_idx].p_cback) {
|
||||
cb_data.req_data.status = status;
|
||||
cb_data.req_data.conn_id = p_msg->api_indicate.hdr.layer_specific;
|
||||
|
||||
(*p_rcb->p_cback)(BTA_GATTS_CONF_EVT, &cb_data);
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_ERROR("Not an registered servce attribute ID: 0x%04x",
|
||||
p_msg->api_indicate.attr_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_open
|
||||
**
|
||||
** Description
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb = NULL;
|
||||
tBTA_GATT_STATUS status = BTA_GATT_ERROR;
|
||||
UINT16 conn_id;
|
||||
UNUSED(p_cb);
|
||||
|
||||
if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_open.server_if)) != NULL) {
|
||||
/* should always get the connection ID */
|
||||
if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda,
|
||||
p_msg->api_open.is_direct, p_msg->api_open.transport)) {
|
||||
status = BTA_GATT_OK;
|
||||
|
||||
if (GATT_GetConnIdIfConnected(p_rcb->gatt_if, p_msg->api_open.remote_bda,
|
||||
&conn_id, p_msg->api_open.transport)) {
|
||||
status = BTA_GATT_ALREADY_OPEN;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_open.server_if);
|
||||
}
|
||||
|
||||
if (p_rcb && p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_OPEN_EVT, (tBTA_GATTS *)&status);
|
||||
}
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_cancel_open
|
||||
**
|
||||
** Description
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_cancel_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb;
|
||||
tBTA_GATT_STATUS status = BTA_GATT_ERROR;
|
||||
UNUSED(p_cb);
|
||||
|
||||
if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_cancel_open.server_if)) != NULL) {
|
||||
if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda,
|
||||
p_msg->api_cancel_open.is_direct)) {
|
||||
APPL_TRACE_ERROR("bta_gatts_cancel_open failed for open request");
|
||||
} else {
|
||||
status = BTA_GATT_OK;
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_cancel_open.server_if);
|
||||
}
|
||||
|
||||
if (p_rcb && p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_CANCEL_OPEN_EVT, (tBTA_GATTS *)&status);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_close
|
||||
**
|
||||
** Description
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb;
|
||||
tBTA_GATT_STATUS status = BTA_GATT_ERROR;
|
||||
tGATT_IF gatt_if;
|
||||
BD_ADDR remote_bda;
|
||||
tBTA_GATT_TRANSPORT transport;
|
||||
|
||||
UNUSED(p_cb);
|
||||
|
||||
if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda, &transport)) {
|
||||
if (GATT_Disconnect(p_msg->hdr.layer_specific) != GATT_SUCCESS) {
|
||||
APPL_TRACE_ERROR("bta_gatts_close fail conn_id=%d", p_msg->hdr.layer_specific);
|
||||
} else {
|
||||
status = BTA_GATT_OK;
|
||||
}
|
||||
|
||||
p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
|
||||
|
||||
if (p_rcb && p_rcb->p_cback) {
|
||||
if (transport == BTA_TRANSPORT_BR_EDR) {
|
||||
bta_sys_conn_close( BTA_ID_GATTS , BTA_ALL_APP_ID, remote_bda);
|
||||
}
|
||||
|
||||
(*p_rcb->p_cback)(BTA_GATTS_CLOSE_EVT, (tBTA_GATTS *)&status);
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_ERROR("Unknown connection ID: %d", p_msg->hdr.layer_specific);
|
||||
}
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_listen
|
||||
**
|
||||
** Description Start or stop listening for LE connection on a GATT server
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_listen.server_if);
|
||||
tBTA_GATTS cb_data;
|
||||
UNUSED(p_cb);
|
||||
|
||||
cb_data.reg_oper.status = BTA_GATT_OK;
|
||||
cb_data.reg_oper.server_if = p_msg->api_listen.server_if;
|
||||
|
||||
if (p_rcb == NULL) {
|
||||
APPL_TRACE_ERROR("Unknown GATTS application");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GATT_Listen(p_msg->api_listen.server_if,
|
||||
p_msg->api_listen.start,
|
||||
p_msg->api_listen.remote_bda)) {
|
||||
cb_data.status = BTA_GATT_ERROR;
|
||||
APPL_TRACE_ERROR("bta_gatts_listen Listen failed");
|
||||
}
|
||||
|
||||
if (p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_LISTEN_EVT, &cb_data);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_request_cback
|
||||
**
|
||||
** Description GATTS attribute request callback.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_gatts_send_request_cback (UINT16 conn_id,
|
||||
UINT32 trans_id,
|
||||
tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data)
|
||||
{
|
||||
tBTA_GATTS cb_data;
|
||||
tBTA_GATTS_RCB *p_rcb;
|
||||
tGATT_IF gatt_if;
|
||||
tBTA_GATT_TRANSPORT transport;
|
||||
|
||||
memset(&cb_data, 0 , sizeof(tBTA_GATTS));
|
||||
|
||||
if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport)) {
|
||||
p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
|
||||
|
||||
APPL_TRACE_DEBUG ("bta_gatts_send_request_cback conn_id=%d trans_id=%d req_type=%d",
|
||||
conn_id, trans_id, req_type);
|
||||
|
||||
if (p_rcb && p_rcb->p_cback) {
|
||||
/* if over BR_EDR, inform PM for mode change */
|
||||
if (transport == BTA_TRANSPORT_BR_EDR) {
|
||||
bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
|
||||
bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
|
||||
}
|
||||
|
||||
cb_data.req_data.conn_id = conn_id;
|
||||
cb_data.req_data.trans_id = trans_id;
|
||||
cb_data.req_data.p_data = (tBTA_GATTS_REQ_DATA *)p_data;
|
||||
|
||||
(*p_rcb->p_cback)(req_type, &cb_data);
|
||||
} else {
|
||||
APPL_TRACE_ERROR("connection request on gatt_if[%d] is not interested", gatt_if);
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_ERROR("request received on unknown connection ID: %d", conn_id);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_conn_cback
|
||||
**
|
||||
** Description connection callback.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
|
||||
BOOLEAN connected, tGATT_DISCONN_REASON reason,
|
||||
tGATT_TRANSPORT transport)
|
||||
{
|
||||
tBTA_GATTS cb_data;
|
||||
UINT8 evt = connected ? BTA_GATTS_CONNECT_EVT : BTA_GATTS_DISCONNECT_EVT;
|
||||
tBTA_GATTS_RCB *p_reg;
|
||||
|
||||
APPL_TRACE_DEBUG ("bta_gatts_conn_cback gatt_if=%d conn_id=%d connected=%d reason = 0x%04d",
|
||||
gatt_if, conn_id, connected, reason);
|
||||
APPL_TRACE_DEBUG("bta_gatts_conn_cback bda :%02x-%02x-%02x-%02x-%02x-%02x ",
|
||||
bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
|
||||
|
||||
bt_bdaddr_t bdaddr;
|
||||
bdcpy(bdaddr.address, bda);
|
||||
/*
|
||||
if (connected)
|
||||
btif_debug_conn_state(bdaddr, BTIF_DEBUG_CONNECTED, GATT_CONN_UNKNOWN);
|
||||
else
|
||||
btif_debug_conn_state(bdaddr, BTIF_DEBUG_DISCONNECTED, reason);
|
||||
*/
|
||||
p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if);
|
||||
|
||||
if (p_reg && p_reg->p_cback) {
|
||||
/* there is no RM for GATT */
|
||||
if (transport == BTA_TRANSPORT_BR_EDR) {
|
||||
if (connected) {
|
||||
bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bda);
|
||||
} else {
|
||||
bta_sys_conn_close( BTA_ID_GATTS , BTA_ALL_APP_ID, bda);
|
||||
}
|
||||
}
|
||||
|
||||
cb_data.conn.conn_id = conn_id;
|
||||
cb_data.conn.server_if = gatt_if;
|
||||
cb_data.conn.reason = reason;
|
||||
cb_data.conn.transport = transport;
|
||||
memcpy(cb_data.conn.remote_bda, bda, BD_ADDR_LEN);
|
||||
(*p_reg->p_cback)(evt, &cb_data);
|
||||
} else {
|
||||
APPL_TRACE_ERROR("bta_gatts_conn_cback server_if=%d not found", gatt_if);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_cong_cback
|
||||
**
|
||||
** Description congestion callback.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb;
|
||||
tGATT_IF gatt_if;
|
||||
tBTA_GATT_TRANSPORT transport;
|
||||
tBTA_GATTS cb_data;
|
||||
|
||||
if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport)) {
|
||||
p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
|
||||
|
||||
if (p_rcb && p_rcb->p_cback) {
|
||||
cb_data.congest.conn_id = conn_id;
|
||||
cb_data.congest.congested = congested;
|
||||
|
||||
(*p_rcb->p_cback)(BTA_GATTS_CONGEST_EVT, &cb_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* BTA_GATT_INCLUDED */
|
||||
619
components/bt/bluedroid/bta/gatt/bta_gatts_api.c
Normal file
619
components/bt/bluedroid/bta/gatt/bta_gatts_api.c
Normal file
@@ -0,0 +1,619 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the implementation of the API for GATT server of BTA.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
|
||||
#if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
|
||||
|
||||
#include <string.h>
|
||||
#include "gki.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_gatt_api.h"
|
||||
#include "bta_gatts_int.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
|
||||
static const tBTA_SYS_REG bta_gatts_reg = {
|
||||
bta_gatts_hdl_event,
|
||||
BTA_GATTS_Disable
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_Disable
|
||||
**
|
||||
** Description This function is called to disable GATTS module
|
||||
**
|
||||
** Parameters None.
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_Disable(void)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if (bta_sys_is_register(BTA_ID_GATTS) == FALSE) {
|
||||
APPL_TRACE_WARNING("GATTS Module not enabled/already disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_GATTS_API_DISABLE_EVT;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
bta_sys_deregister(BTA_ID_GATTS);
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_AppRegister
|
||||
**
|
||||
** Description This function is called to register application callbacks
|
||||
** with BTA GATTS module.
|
||||
**
|
||||
** Parameters p_app_uuid - applicaiton UUID
|
||||
** p_cback - pointer to the application callback function.
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_AppRegister(tBT_UUID *p_app_uuid, tBTA_GATTS_CBACK *p_cback)
|
||||
{
|
||||
tBTA_GATTS_API_REG *p_buf;
|
||||
|
||||
/* register with BTA system manager */
|
||||
if (bta_sys_is_register(BTA_ID_GATTS) == FALSE) {
|
||||
bta_sys_register(BTA_ID_GATTS, &bta_gatts_reg);
|
||||
}
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_REG *) GKI_getbuf(sizeof(tBTA_GATTS_API_REG))) != NULL) {
|
||||
p_buf->hdr.event = BTA_GATTS_API_REG_EVT;
|
||||
|
||||
if (p_app_uuid != NULL) {
|
||||
memcpy(&p_buf->app_uuid, p_app_uuid, sizeof(tBT_UUID));
|
||||
}
|
||||
p_buf->p_cback = p_cback;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_AppDeregister
|
||||
**
|
||||
** Description De-register with GATT Server.
|
||||
**
|
||||
** Parameters app_id: applicatino ID.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_AppDeregister(tBTA_GATTS_IF server_if)
|
||||
{
|
||||
tBTA_GATTS_API_DEREG *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_DEREG *) GKI_getbuf(sizeof(tBTA_GATTS_API_DEREG))) != NULL) {
|
||||
p_buf->hdr.event = BTA_GATTS_API_DEREG_EVT;
|
||||
p_buf->server_if = server_if;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_CreateService
|
||||
**
|
||||
** Description Create a service. When service creation is done, a callback
|
||||
** event BTA_GATTS_CREATE_SRVC_EVT is called to report status
|
||||
** and service ID to the profile. The service ID obtained in
|
||||
** the callback function needs to be used when adding included
|
||||
** service and characteristics/descriptors into the service.
|
||||
**
|
||||
** Parameters app_id: Profile ID this service is belonged to.
|
||||
** p_service_uuid: service UUID.
|
||||
** inst: instance ID number of this service.
|
||||
** num_handle: numble of handle requessted for this service.
|
||||
** is_primary: is this service a primary one or not.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_CreateService(tBTA_GATTS_IF server_if, tBT_UUID *p_service_uuid, UINT8 inst,
|
||||
UINT16 num_handle, BOOLEAN is_primary)
|
||||
{
|
||||
tBTA_GATTS_API_CREATE_SRVC *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_CREATE_SRVC *) GKI_getbuf(sizeof(tBTA_GATTS_API_CREATE_SRVC))) != NULL) {
|
||||
p_buf->hdr.event = BTA_GATTS_API_CREATE_SRVC_EVT;
|
||||
|
||||
p_buf->server_if = server_if;
|
||||
p_buf->inst = inst;
|
||||
memcpy(&p_buf->service_uuid, p_service_uuid, sizeof(tBT_UUID));
|
||||
p_buf->num_handle = num_handle;
|
||||
p_buf->is_pri = is_primary;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_AddIncludeService
|
||||
**
|
||||
** Description This function is called to add an included service. After included
|
||||
** service is included, a callback event BTA_GATTS_ADD_INCL_SRVC_EVT
|
||||
** is reported the included service ID.
|
||||
**
|
||||
** Parameters service_id: service ID to which this included service is to
|
||||
** be added.
|
||||
** included_service_id: the service ID to be included.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_AddIncludeService(UINT16 service_id, UINT16 included_service_id)
|
||||
{
|
||||
tBTA_GATTS_API_ADD_INCL_SRVC *p_buf;
|
||||
|
||||
if ((p_buf =
|
||||
(tBTA_GATTS_API_ADD_INCL_SRVC *) GKI_getbuf(sizeof(tBTA_GATTS_API_ADD_INCL_SRVC)))
|
||||
!= NULL) {
|
||||
p_buf->hdr.event = BTA_GATTS_API_ADD_INCL_SRVC_EVT;
|
||||
|
||||
p_buf->hdr.layer_specific = service_id;
|
||||
p_buf->included_service_id = included_service_id;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_AddCharacteristic
|
||||
**
|
||||
** Description This function is called to add a characteristic into a service.
|
||||
**
|
||||
** Parameters service_id: service ID to which this included service is to
|
||||
** be added.
|
||||
** p_char_uuid : Characteristic UUID.
|
||||
** perm : Characteristic value declaration attribute permission.
|
||||
** property : Characteristic Properties
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_AddCharacteristic (UINT16 service_id, tBT_UUID *p_char_uuid,
|
||||
tBTA_GATT_PERM perm, tBTA_GATT_CHAR_PROP property, tGATT_ATTR_VAL *attr_val,
|
||||
tBTA_GATTS_ATTR_CONTROL *control)
|
||||
{
|
||||
tBTA_GATTS_API_ADD_CHAR *p_buf;
|
||||
UINT16 len = 0;
|
||||
if(attr_val != NULL){
|
||||
len = attr_val->attr_len;
|
||||
}
|
||||
if ((p_buf = (tBTA_GATTS_API_ADD_CHAR *) GKI_getbuf(sizeof(tBTA_GATTS_API_ADD_CHAR))) != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_GATTS_API_ADD_CHAR));
|
||||
|
||||
p_buf->hdr.event = BTA_GATTS_API_ADD_CHAR_EVT;
|
||||
p_buf->hdr.layer_specific = service_id;
|
||||
p_buf->perm = perm;
|
||||
p_buf->property = property;
|
||||
if(control !=NULL){
|
||||
p_buf->control.auto_rsp = control->auto_rsp;
|
||||
}
|
||||
if(attr_val != NULL){
|
||||
APPL_TRACE_DEBUG("!!!!!!attr_val->attr_len = %x\n",attr_val->attr_len);
|
||||
APPL_TRACE_DEBUG("!!!!!!!attr_val->attr_max_len = %x\n",attr_val->attr_max_len);
|
||||
p_buf->attr_val.attr_len = attr_val->attr_len;
|
||||
p_buf->attr_val.attr_max_len = attr_val->attr_max_len;
|
||||
p_buf->attr_val.attr_val = (uint8_t *)GKI_getbuf(len);
|
||||
if(p_buf->attr_val.attr_val != NULL){
|
||||
memcpy(p_buf->attr_val.attr_val, attr_val->attr_val, attr_val->attr_len);
|
||||
}
|
||||
}
|
||||
|
||||
if (p_char_uuid) {
|
||||
memcpy(&p_buf->char_uuid, p_char_uuid, sizeof(tBT_UUID));
|
||||
}
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_AddCharDescriptor
|
||||
**
|
||||
** Description This function is called to add characteristic descriptor. When
|
||||
** it's done, a callback event BTA_GATTS_ADD_DESCR_EVT is called
|
||||
** to report the status and an ID number for this descriptor.
|
||||
**
|
||||
** Parameters service_id: service ID to which this charatceristic descriptor is to
|
||||
** be added.
|
||||
** perm: descriptor access permission.
|
||||
** p_descr_uuid: descriptor UUID.
|
||||
**
|
||||
** Returns returns status.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_AddCharDescriptor (UINT16 service_id,
|
||||
tBTA_GATT_PERM perm,
|
||||
tBT_UUID *p_descr_uuid, tBTA_GATT_ATTR_VAL *attr_val,
|
||||
tBTA_GATTS_ATTR_CONTROL *control)
|
||||
{
|
||||
tBTA_GATTS_API_ADD_DESCR *p_buf;
|
||||
UINT16 value_len = 0;
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_ADD_DESCR *) GKI_getbuf(sizeof(tBTA_GATTS_API_ADD_DESCR))) != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_GATTS_API_ADD_DESCR));
|
||||
|
||||
p_buf->hdr.event = BTA_GATTS_API_ADD_DESCR_EVT;
|
||||
p_buf->hdr.layer_specific = service_id;
|
||||
p_buf->perm = perm;
|
||||
|
||||
if(control != NULL){
|
||||
p_buf->control.auto_rsp = control->auto_rsp;
|
||||
}
|
||||
|
||||
if (p_descr_uuid) {
|
||||
memcpy(&p_buf->descr_uuid, p_descr_uuid, sizeof(tBT_UUID));
|
||||
}
|
||||
|
||||
if(attr_val != NULL){
|
||||
p_buf->attr_val.attr_len = attr_val->attr_len;
|
||||
p_buf->attr_val.attr_max_len = attr_val->attr_max_len;
|
||||
value_len = attr_val->attr_len;
|
||||
if (value_len != 0){
|
||||
p_buf->attr_val.attr_val = (uint8_t*)GKI_getbuf(value_len);
|
||||
if(p_buf->attr_val.attr_val != NULL){
|
||||
memcpy(p_buf->attr_val.attr_val, attr_val->attr_val, value_len);
|
||||
}
|
||||
else{
|
||||
APPL_TRACE_ERROR("Allocate fail for %s\n", __func__);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_DeleteService
|
||||
**
|
||||
** Description This function is called to delete a service. When this is done,
|
||||
** a callback event BTA_GATTS_DELETE_EVT is report with the status.
|
||||
**
|
||||
** Parameters service_id: service_id to be deleted.
|
||||
**
|
||||
** Returns returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_DeleteService(UINT16 service_id)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_GATTS_API_DEL_SRVC_EVT;
|
||||
|
||||
p_buf->layer_specific = service_id;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_StartService
|
||||
**
|
||||
** Description This function is called to start a service.
|
||||
**
|
||||
** Parameters service_id: the service ID to be started.
|
||||
** sup_transport: supported trasnport.
|
||||
**
|
||||
** Returns None.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_StartService(UINT16 service_id, tBTA_GATT_TRANSPORT sup_transport)
|
||||
{
|
||||
tBTA_GATTS_API_START *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_START *) GKI_getbuf(sizeof(tBTA_GATTS_API_START))) != NULL) {
|
||||
p_buf->hdr.event = BTA_GATTS_API_START_SRVC_EVT;
|
||||
|
||||
p_buf->hdr.layer_specific = service_id;
|
||||
p_buf->transport = sup_transport;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_StopService
|
||||
**
|
||||
** Description This function is called to stop a service.
|
||||
**
|
||||
** Parameters service_id - service to be topped.
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_StopService(UINT16 service_id)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_GATTS_API_STOP_SRVC_EVT;
|
||||
|
||||
p_buf->layer_specific = service_id;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_HandleValueIndication
|
||||
**
|
||||
** Description This function is called to read a characteristics descriptor.
|
||||
**
|
||||
** Parameters bda - remote device bd address to indicate.
|
||||
** attr_id - attribute ID to indicate.
|
||||
** data_len - indicate data length.
|
||||
** p_data: data to indicate.
|
||||
** need_confirm - if this indication expects a confirmation or not.
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_HandleValueIndication (UINT16 conn_id, UINT16 attr_id, UINT16 data_len,
|
||||
UINT8 *p_data, BOOLEAN need_confirm)
|
||||
{
|
||||
tBTA_GATTS_API_INDICATION *p_buf;
|
||||
UINT16 len = sizeof(tBTA_GATTS_API_INDICATION);
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_INDICATION *) GKI_getbuf(len)) != NULL) {
|
||||
memset(p_buf, 0, len);
|
||||
|
||||
p_buf->hdr.event = BTA_GATTS_API_INDICATION_EVT;
|
||||
p_buf->hdr.layer_specific = conn_id;
|
||||
p_buf->attr_id = attr_id;
|
||||
p_buf->need_confirm = need_confirm;
|
||||
|
||||
if (data_len > 0 && p_data != NULL) {
|
||||
p_buf->len = data_len;
|
||||
memcpy(p_buf->value, p_data, data_len);
|
||||
|
||||
}
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_SendRsp
|
||||
**
|
||||
** Description This function is called to send a response to a request.
|
||||
**
|
||||
** Parameters conn_id - connection identifier.
|
||||
** trans_id - transaction ID.
|
||||
** status - response status
|
||||
** p_msg - response data.
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_SendRsp (UINT16 conn_id, UINT32 trans_id,
|
||||
tBTA_GATT_STATUS status, tBTA_GATTS_RSP *p_msg)
|
||||
{
|
||||
tBTA_GATTS_API_RSP *p_buf;
|
||||
UINT16 len = sizeof(tBTA_GATTS_API_RSP) + sizeof(tBTA_GATTS_RSP);
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_RSP *) GKI_getbuf(len)) != NULL) {
|
||||
memset(p_buf, 0, len);
|
||||
|
||||
p_buf->hdr.event = BTA_GATTS_API_RSP_EVT;
|
||||
p_buf->hdr.layer_specific = conn_id;
|
||||
p_buf->trans_id = trans_id;
|
||||
p_buf->status = status;
|
||||
|
||||
if (p_msg != NULL) {
|
||||
p_buf->p_rsp = (tBTA_GATTS_RSP *)(p_buf + 1);
|
||||
memcpy(p_buf->p_rsp, p_msg, sizeof(tBTA_GATTS_RSP));
|
||||
}
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void BTA_SetAttributeValue(UINT16 attr_handle, UINT16 length, UINT8 *value)
|
||||
{
|
||||
tBTA_GATTS_API_SET_ATTR_VAL *p_buf;
|
||||
if((p_buf = (tBTA_GATTS_API_SET_ATTR_VAL *)GKI_getbuf(
|
||||
sizeof(tBTA_GATTS_API_SET_ATTR_VAL))) != NULL){
|
||||
p_buf->hdr.event = BTA_GATTS_API_SET_ATTR_VAL_EVT;
|
||||
p_buf->hdr.layer_specific = attr_handle;
|
||||
p_buf->length = length;
|
||||
if(value != NULL){
|
||||
if((p_buf->value = (UINT8 *)GKI_getbuf(length)) != NULL){
|
||||
memcpy(p_buf->value, value, length);
|
||||
}
|
||||
}
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void BTA_GetAttributeValue(UINT16 attr_handle, UINT16 *length, UINT8 **value)
|
||||
{
|
||||
bta_gatts_get_attr_value(attr_handle, length, value);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_Open
|
||||
**
|
||||
** Description Open a direct open connection or add a background auto connection
|
||||
** bd address
|
||||
**
|
||||
** Parameters server_if: server interface.
|
||||
** remote_bda: remote device BD address.
|
||||
** is_direct: direct connection or background auto connection
|
||||
** transport : Transport on which GATT connection to be opened (BR/EDR or LE)
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct,
|
||||
tBTA_GATT_TRANSPORT transport)
|
||||
{
|
||||
tBTA_GATTS_API_OPEN *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_OPEN *) GKI_getbuf(sizeof(tBTA_GATTS_API_OPEN))) != NULL) {
|
||||
p_buf->hdr.event = BTA_GATTS_API_OPEN_EVT;
|
||||
p_buf->server_if = server_if;
|
||||
p_buf->is_direct = is_direct;
|
||||
p_buf->transport = transport;
|
||||
memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_CancelOpen
|
||||
**
|
||||
** Description Cancel a direct open connection or remove a background auto connection
|
||||
** bd address
|
||||
**
|
||||
** Parameters server_if: server interface.
|
||||
** remote_bda: remote device BD address.
|
||||
** is_direct: direct connection or background auto connection
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_CancelOpen(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct)
|
||||
{
|
||||
tBTA_GATTS_API_CANCEL_OPEN *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_CANCEL_OPEN *) GKI_getbuf(sizeof(tBTA_GATTS_API_CANCEL_OPEN))) != NULL) {
|
||||
p_buf->hdr.event = BTA_GATTS_API_CANCEL_OPEN_EVT;
|
||||
p_buf->server_if = server_if;
|
||||
p_buf->is_direct = is_direct;
|
||||
memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_Close
|
||||
**
|
||||
** Description Close a connection a remote device.
|
||||
**
|
||||
** Parameters conn_id: connection ID to be closed.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_Close(UINT16 conn_id)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_GATTS_API_CLOSE_EVT;
|
||||
p_buf->layer_specific = conn_id;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_Listen
|
||||
**
|
||||
** Description Start advertisement to listen for connection request for a
|
||||
** GATT server
|
||||
**
|
||||
** Parameters server_if: server interface.
|
||||
** start: to start or stop listening for connection
|
||||
** remote_bda: remote device BD address, if listen to all device
|
||||
** use NULL.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_Listen(tBTA_GATTS_IF server_if, BOOLEAN start, BD_ADDR_PTR target_bda)
|
||||
{
|
||||
tBTA_GATTS_API_LISTEN *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_LISTEN *) GKI_getbuf((UINT16)(sizeof(tBTA_GATTS_API_LISTEN) + BD_ADDR_LEN))) != NULL) {
|
||||
p_buf->hdr.event = BTA_GATTS_API_LISTEN_EVT;
|
||||
|
||||
p_buf->server_if = server_if;
|
||||
p_buf->start = start;
|
||||
|
||||
if (target_bda) {
|
||||
p_buf->remote_bda = (UINT8 *)(p_buf + 1);
|
||||
memcpy(p_buf->remote_bda, target_bda, BD_ADDR_LEN);
|
||||
} else {
|
||||
p_buf->remote_bda = NULL;
|
||||
}
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* BTA_GATT_INCLUDED */
|
||||
139
components/bt/bluedroid/bta/gatt/bta_gatts_main.c
Normal file
139
components/bt/bluedroid/bta/gatt/bta_gatts_main.c
Normal file
@@ -0,0 +1,139 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the GATT server main functions and state machine.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
|
||||
#if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "bta_gatts_int.h"
|
||||
#include "gki.h"
|
||||
|
||||
/* type for service building action functions */
|
||||
typedef void (*tBTA_GATTS_SRVC_ACT)(tBTA_GATTS_SRVC_CB *p_rcb, tBTA_GATTS_DATA *p_data);
|
||||
|
||||
/* service building action function list */
|
||||
const tBTA_GATTS_SRVC_ACT bta_gatts_srvc_build_act[] = {
|
||||
bta_gatts_add_include_srvc,
|
||||
bta_gatts_add_char,
|
||||
bta_gatts_add_char_descr,
|
||||
bta_gatts_delete_service,
|
||||
bta_gatts_start_service,
|
||||
bta_gatts_stop_service,
|
||||
};
|
||||
|
||||
/* GATTS control block */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
tBTA_GATTS_CB bta_gatts_cb;
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_hdl_event
|
||||
**
|
||||
** Description BTA GATT server main event handling function.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gatts_hdl_event(BT_HDR *p_msg)
|
||||
{
|
||||
tBTA_GATTS_CB *p_cb = &bta_gatts_cb;
|
||||
tBTA_GATTS_SRVC_CB *p_srvc_cb = NULL;
|
||||
|
||||
switch (p_msg->event) {
|
||||
case BTA_GATTS_API_DISABLE_EVT:
|
||||
bta_gatts_api_disable(p_cb);
|
||||
break;
|
||||
|
||||
case BTA_GATTS_API_REG_EVT:
|
||||
bta_gatts_register(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTS_INT_START_IF_EVT:
|
||||
bta_gatts_start_if(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTS_API_DEREG_EVT:
|
||||
bta_gatts_deregister(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTS_API_CREATE_SRVC_EVT:
|
||||
bta_gatts_create_srvc(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTS_API_INDICATION_EVT:
|
||||
bta_gatts_indicate_handle(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTS_API_OPEN_EVT:
|
||||
bta_gatts_open(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTS_API_CANCEL_OPEN_EVT:
|
||||
bta_gatts_cancel_open(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTS_API_CLOSE_EVT:
|
||||
bta_gatts_close(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTS_API_RSP_EVT:
|
||||
bta_gatts_send_rsp(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
case BTA_GATTS_API_SET_ATTR_VAL_EVT:{
|
||||
UINT16 attr_id = ((tBTA_GATTS_DATA *) p_msg)->api_set_val.hdr.layer_specific;
|
||||
p_srvc_cb = bta_gatts_find_srvc_cb_by_attr_id(p_cb, attr_id);
|
||||
bta_gatts_set_attr_value(p_srvc_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
}
|
||||
case BTA_GATTS_API_LISTEN_EVT:
|
||||
bta_gatts_listen(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
case BTA_GATTS_API_ADD_INCL_SRVC_EVT:
|
||||
case BTA_GATTS_API_ADD_CHAR_EVT:
|
||||
case BTA_GATTS_API_ADD_DESCR_EVT:
|
||||
case BTA_GATTS_API_DEL_SRVC_EVT:
|
||||
case BTA_GATTS_API_START_SRVC_EVT:
|
||||
case BTA_GATTS_API_STOP_SRVC_EVT:
|
||||
p_srvc_cb = bta_gatts_find_srvc_cb_by_srvc_id(p_cb,
|
||||
((tBTA_GATTS_DATA *)p_msg)->api_add_incl_srvc.hdr.layer_specific);
|
||||
|
||||
if (p_srvc_cb != NULL) {
|
||||
bta_gatts_srvc_build_act[p_msg->event - BTA_GATTS_API_ADD_INCL_SRVC_EVT](p_srvc_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
} else {
|
||||
APPL_TRACE_ERROR("service not created\n");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
#endif /* BTA_GATT_INCLUDED */
|
||||
225
components/bt/bluedroid/bta/gatt/bta_gatts_utils.c
Normal file
225
components/bt/bluedroid/bta/gatt/bta_gatts_utils.c
Normal file
@@ -0,0 +1,225 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the GATT client utility function.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
|
||||
#if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
|
||||
|
||||
#include <string.h>
|
||||
#include "utl.h"
|
||||
#include "gki.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_gatts_int.h"
|
||||
|
||||
static const UINT8 base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
|
||||
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatt_convert_uuid16_to_uuid128
|
||||
**
|
||||
** Description Convert a 16 bits UUID to be an standard 128 bits one.
|
||||
**
|
||||
** Returns TRUE if two uuid match; FALSE otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16)
|
||||
{
|
||||
UINT8 *p = &uuid_128[LEN_UUID_128 - 4];
|
||||
|
||||
memcpy (uuid_128, base_uuid, LEN_UUID_128);
|
||||
|
||||
UINT16_TO_STREAM(p, uuid_16);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_alloc_srvc_cb
|
||||
**
|
||||
** Description allocate a service control block.
|
||||
**
|
||||
** Returns pointer to the control block, or otherwise NULL when failed.
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT8 bta_gatts_alloc_srvc_cb(tBTA_GATTS_CB *p_cb, UINT8 rcb_idx)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < BTA_GATTS_MAX_SRVC_NUM; i ++) {
|
||||
if (!p_cb->srvc_cb[i].in_use) {
|
||||
p_cb->srvc_cb[i].in_use = TRUE;
|
||||
p_cb->srvc_cb[i].rcb_idx = rcb_idx;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return BTA_GATTS_INVALID_APP;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_find_app_rcb_by_app_if
|
||||
**
|
||||
** Description find the index of the application control block by app ID.
|
||||
**
|
||||
** Returns pointer to the control block if success, otherwise NULL
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTS_RCB *bta_gatts_find_app_rcb_by_app_if(tBTA_GATTS_IF server_if)
|
||||
{
|
||||
UINT8 i;
|
||||
tBTA_GATTS_RCB *p_reg;
|
||||
|
||||
for (i = 0, p_reg = bta_gatts_cb.rcb; i < BTA_GATTS_MAX_APP_NUM; i ++, p_reg++) {
|
||||
if (p_reg->in_use && p_reg->gatt_if == server_if) {
|
||||
return p_reg;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_find_app_rcb_idx_by_app_if
|
||||
**
|
||||
** Description find the index of the application control block by app ID.
|
||||
**
|
||||
** Returns index of the control block, or BTA_GATTS_INVALID_APP if failed.
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
||||
UINT8 bta_gatts_find_app_rcb_idx_by_app_if(tBTA_GATTS_CB *p_cb, tBTA_GATTS_IF server_if)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++) {
|
||||
if (p_cb->rcb[i].in_use && p_cb->rcb[i].gatt_if == server_if) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return BTA_GATTS_INVALID_APP;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_find_srvc_cb_by_srvc_id
|
||||
**
|
||||
** Description find the service control block by service ID.
|
||||
**
|
||||
** Returns pointer to the rcb.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTS_SRVC_CB *bta_gatts_find_srvc_cb_by_srvc_id(tBTA_GATTS_CB *p_cb, UINT16 service_id)
|
||||
{
|
||||
UINT8 i;
|
||||
APPL_TRACE_DEBUG("bta_gatts_find_srvc_cb_by_srvc_id service_id=%d", service_id);
|
||||
for (i = 0; i < BTA_GATTS_MAX_SRVC_NUM; i ++) {
|
||||
if (p_cb->srvc_cb[i].in_use &&
|
||||
p_cb->srvc_cb[i].service_id == service_id) {
|
||||
APPL_TRACE_DEBUG("bta_gatts_find_srvc_cb_by_srvc_id found service cb index =%d", i);
|
||||
return &p_cb->srvc_cb[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_find_srvc_cb_by_attr_id
|
||||
**
|
||||
** Description find the service control block by attribute ID.
|
||||
**
|
||||
** Returns pointer to the rcb.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTS_SRVC_CB *bta_gatts_find_srvc_cb_by_attr_id(tBTA_GATTS_CB *p_cb, UINT16 attr_id)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < (BTA_GATTS_MAX_SRVC_NUM); i ++) {
|
||||
if (/* middle service */
|
||||
(i < (BTA_GATTS_MAX_SRVC_NUM - 1) &&
|
||||
p_cb->srvc_cb[i].in_use &&
|
||||
p_cb->srvc_cb[i + 1].in_use &&
|
||||
attr_id >= p_cb->srvc_cb[i].service_id &&
|
||||
attr_id < p_cb->srvc_cb[i + 1].service_id) ||
|
||||
/* last active service */
|
||||
(i < (BTA_GATTS_MAX_SRVC_NUM - 1) &&
|
||||
p_cb->srvc_cb[i].in_use &&
|
||||
!p_cb->srvc_cb[i + 1].in_use &&
|
||||
attr_id >= p_cb->srvc_cb[i].service_id) ||
|
||||
/* last service incb */
|
||||
(i == (BTA_GATTS_MAX_SRVC_NUM - 1) &&
|
||||
attr_id >= p_cb->srvc_cb[i].service_id)
|
||||
) {
|
||||
return &p_cb->srvc_cb[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_uuid_compare
|
||||
**
|
||||
** Description Compare two UUID to see if they are the same.
|
||||
**
|
||||
** Returns TRUE if two uuid match; FALSE otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gatts_uuid_compare(tBT_UUID tar, tBT_UUID src)
|
||||
{
|
||||
UINT8 su[LEN_UUID_128], tu[LEN_UUID_128];
|
||||
UINT8 *ps, *pt;
|
||||
|
||||
/* any of the UUID is unspecified */
|
||||
if (src.len == 0 || tar.len == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* If both are 16-bit, we can do a simple compare */
|
||||
if (src.len == 2 && tar.len == 2) {
|
||||
return src.uu.uuid16 == tar.uu.uuid16;
|
||||
}
|
||||
|
||||
/* One or both of the UUIDs is 128-bit */
|
||||
if (src.len == LEN_UUID_16) {
|
||||
/* convert a 16 bits UUID to 128 bits value */
|
||||
bta_gatt_convert_uuid16_to_uuid128(su, src.uu.uuid16);
|
||||
ps = su;
|
||||
} else {
|
||||
ps = src.uu.uuid128;
|
||||
}
|
||||
|
||||
if (tar.len == LEN_UUID_16) {
|
||||
/* convert a 16 bits UUID to 128 bits value */
|
||||
bta_gatt_convert_uuid16_to_uuid128(tu, tar.uu.uuid16);
|
||||
pt = tu;
|
||||
} else {
|
||||
pt = tar.uu.uuid128;
|
||||
}
|
||||
|
||||
return (memcmp(ps, pt, LEN_UUID_128) == 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
1251
components/bt/bluedroid/bta/hh/bta_hh_act.c
Normal file
1251
components/bt/bluedroid/bta/hh/bta_hh_act.c
Normal file
File diff suppressed because it is too large
Load Diff
478
components/bt/bluedroid/bta/hh/bta_hh_api.c
Normal file
478
components/bt/bluedroid/bta/hh/bta_hh_api.c
Normal file
@@ -0,0 +1,478 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the HID HOST API in the subsystem of BTA.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
|
||||
#if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bta_hh_api.h"
|
||||
#include "bta_hh_int.h"
|
||||
#include "l2c_api.h"
|
||||
#include "utl.h"
|
||||
|
||||
#define LOG_TAG "bt_bta_hh"
|
||||
#include "osi/include/log.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
|
||||
static const tBTA_SYS_REG bta_hh_reg = {
|
||||
bta_hh_hdl_event,
|
||||
BTA_HhDisable
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhEnable
|
||||
**
|
||||
** Description Enable the HID host. This function must be called before
|
||||
** any other functions in the HID host API are called. When the
|
||||
** enable operation is complete the callback function will be
|
||||
** called with BTA_HH_ENABLE_EVT.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhEnable(tBTA_SEC sec_mask, tBTA_HH_CBACK *p_cback)
|
||||
{
|
||||
tBTA_HH_API_ENABLE *p_buf;
|
||||
|
||||
/* register with BTA system manager */
|
||||
bta_sys_register(BTA_ID_HH, &bta_hh_reg);
|
||||
|
||||
LOG_INFO("%s sec_mask:0x%x p_cback:%p", __func__, sec_mask, p_cback);
|
||||
p_buf = (tBTA_HH_API_ENABLE *)GKI_getbuf((UINT16)sizeof(tBTA_HH_API_ENABLE));
|
||||
|
||||
if (p_buf != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_HH_API_ENABLE));
|
||||
|
||||
p_buf->hdr.event = BTA_HH_API_ENABLE_EVT;
|
||||
p_buf->p_cback = p_cback;
|
||||
p_buf->sec_mask = sec_mask;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhDisable
|
||||
**
|
||||
** Description Disable the HID host. If the server is currently
|
||||
** connected, the connection will be closed.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhDisable(void)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
bta_sys_deregister(BTA_ID_HH);
|
||||
if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_HH_API_DISABLE_EVT;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhClose
|
||||
**
|
||||
** Description Disconnect a connection.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhClose(UINT8 dev_handle)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if ((p_buf = (BT_HDR *)GKI_getbuf((UINT16)sizeof(BT_HDR))) != NULL) {
|
||||
memset(p_buf, 0, sizeof(BT_HDR));
|
||||
p_buf->event = BTA_HH_API_CLOSE_EVT;
|
||||
p_buf->layer_specific = (UINT16) dev_handle;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhOpen
|
||||
**
|
||||
** Description Connect to a device of specified BD address in specified
|
||||
** protocol mode and security level.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhOpen(BD_ADDR dev_bda, tBTA_HH_PROTO_MODE mode, tBTA_SEC sec_mask)
|
||||
{
|
||||
tBTA_HH_API_CONN *p_buf;
|
||||
|
||||
p_buf = (tBTA_HH_API_CONN *)GKI_getbuf((UINT16)sizeof(tBTA_HH_API_CONN));
|
||||
|
||||
if (p_buf != NULL) {
|
||||
memset((void *)p_buf, 0, sizeof(tBTA_HH_API_CONN));
|
||||
|
||||
p_buf->hdr.event = BTA_HH_API_OPEN_EVT;
|
||||
p_buf->hdr.layer_specific = BTA_HH_INVALID_HANDLE;
|
||||
p_buf->sec_mask = sec_mask;
|
||||
p_buf->mode = mode;
|
||||
bdcpy(p_buf->bd_addr, dev_bda);
|
||||
|
||||
bta_sys_sendmsg((void *)p_buf);
|
||||
} else {
|
||||
APPL_TRACE_ERROR("No resource to send HID host Connect request.");
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_snd_write_dev
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_hh_snd_write_dev(UINT8 dev_handle, UINT8 t_type, UINT8 param,
|
||||
UINT16 data, UINT8 rpt_id, BT_HDR *p_data)
|
||||
{
|
||||
tBTA_HH_CMD_DATA *p_buf;
|
||||
UINT16 len = (UINT16) (sizeof(tBTA_HH_CMD_DATA) );
|
||||
|
||||
if ((p_buf = (tBTA_HH_CMD_DATA *)GKI_getbuf(len)) != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_HH_CMD_DATA));
|
||||
|
||||
p_buf->hdr.event = BTA_HH_API_WRITE_DEV_EVT;
|
||||
p_buf->hdr.layer_specific = (UINT16) dev_handle;
|
||||
p_buf->t_type = t_type;
|
||||
p_buf->data = data;
|
||||
p_buf->param = param;
|
||||
p_buf->p_data = p_data;
|
||||
p_buf->rpt_id = rpt_id;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSetReport
|
||||
**
|
||||
** Description send SET_REPORT to device.
|
||||
**
|
||||
** Parameter dev_handle: device handle
|
||||
** r_type: report type, could be BTA_HH_RPTT_OUTPUT or
|
||||
** BTA_HH_RPTT_FEATURE.
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhSetReport(UINT8 dev_handle, tBTA_HH_RPT_TYPE r_type, BT_HDR *p_data)
|
||||
{
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_SET_REPORT, r_type, 0, 0, p_data);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetReport
|
||||
**
|
||||
** Description Send a GET_REPORT to HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhGetReport(UINT8 dev_handle, tBTA_HH_RPT_TYPE r_type, UINT8 rpt_id, UINT16 buf_size)
|
||||
{
|
||||
UINT8 param = (buf_size) ? (r_type | 0x08) : r_type;
|
||||
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_GET_REPORT, param,
|
||||
buf_size, rpt_id, NULL);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSetProtoMode
|
||||
**
|
||||
** Description This function set the protocol mode at specified HID handle
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhSetProtoMode(UINT8 dev_handle, tBTA_HH_PROTO_MODE p_type)
|
||||
{
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_SET_PROTOCOL, (UINT8)p_type,
|
||||
0, 0, NULL);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetProtoMode
|
||||
**
|
||||
** Description This function get protocol mode information.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhGetProtoMode(UINT8 dev_handle)
|
||||
{
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_GET_PROTOCOL, 0, 0, 0, NULL);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSetIdle
|
||||
**
|
||||
** Description send SET_IDLE to device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhSetIdle(UINT8 dev_handle, UINT16 idle_rate)
|
||||
{
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_SET_IDLE, 0, idle_rate, 0, NULL);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetIdle
|
||||
**
|
||||
** Description Send a GET_IDLE from HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhGetIdle(UINT8 dev_handle)
|
||||
{
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_GET_IDLE, 0, 0, 0, NULL);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSendCtrl
|
||||
**
|
||||
** Description Send a control command to HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhSendCtrl(UINT8 dev_handle, tBTA_HH_TRANS_CTRL_TYPE c_type)
|
||||
{
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_CONTROL, (UINT8)c_type, 0, 0, NULL);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSendData
|
||||
**
|
||||
** Description This function send DATA transaction to HID device.
|
||||
**
|
||||
** Parameter dev_handle: device handle
|
||||
** dev_bda: remote device address
|
||||
** p_data: data to be sent in the DATA transaction; or
|
||||
** the data to be write into the Output Report of a LE HID
|
||||
** device. The report is identified the report ID which is
|
||||
** the value of the byte (UINT8 *)(p_buf + 1) + p_buf->offset.
|
||||
** p_data->layer_specific needs to be set to the report type,
|
||||
** it can be OUTPUT report, or FEATURE report.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhSendData(UINT8 dev_handle, BD_ADDR dev_bda, BT_HDR *p_data)
|
||||
{
|
||||
UNUSED(dev_bda);
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
if (p_data->layer_specific != BTA_HH_RPTT_OUTPUT) {
|
||||
APPL_TRACE_ERROR("ERROR! Wrong report type! Write Command only valid for output report!");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_DATA, (UINT8)p_data->layer_specific, 0, 0, p_data);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetDscpInfo
|
||||
**
|
||||
** Description Get HID device report descriptor
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhGetDscpInfo(UINT8 dev_handle)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if ((p_buf = (BT_HDR *)GKI_getbuf((UINT16)sizeof(BT_HDR))) != NULL) {
|
||||
memset(p_buf, 0, sizeof(BT_HDR));
|
||||
p_buf->event = BTA_HH_API_GET_DSCP_EVT;
|
||||
p_buf->layer_specific = (UINT16) dev_handle;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhAddDev
|
||||
**
|
||||
** Description Add a virtually cabled device into HID-Host device list
|
||||
** to manage and assign a device handle for future API call,
|
||||
** host applciation call this API at start-up to initialize its
|
||||
** virtually cabled devices.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhAddDev(BD_ADDR bda, tBTA_HH_ATTR_MASK attr_mask, UINT8 sub_class,
|
||||
UINT8 app_id, tBTA_HH_DEV_DSCP_INFO dscp_info)
|
||||
{
|
||||
tBTA_HH_MAINT_DEV *p_buf;
|
||||
UINT16 len = sizeof(tBTA_HH_MAINT_DEV) + dscp_info.descriptor.dl_len;
|
||||
|
||||
p_buf = (tBTA_HH_MAINT_DEV *)GKI_getbuf(len);
|
||||
|
||||
if (p_buf != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_HH_MAINT_DEV));
|
||||
|
||||
p_buf->hdr.event = BTA_HH_API_MAINT_DEV_EVT;
|
||||
p_buf->sub_event = BTA_HH_ADD_DEV_EVT;
|
||||
p_buf->hdr.layer_specific = BTA_HH_INVALID_HANDLE;
|
||||
|
||||
p_buf->attr_mask = (UINT16) attr_mask;
|
||||
p_buf->sub_class = sub_class;
|
||||
p_buf->app_id = app_id;
|
||||
bdcpy(p_buf->bda, bda);
|
||||
|
||||
memcpy(&p_buf->dscp_info, &dscp_info, sizeof(tBTA_HH_DEV_DSCP_INFO));
|
||||
if ( dscp_info.descriptor.dl_len != 0 && dscp_info.descriptor.dsc_list) {
|
||||
p_buf->dscp_info.descriptor.dl_len = dscp_info.descriptor.dl_len;
|
||||
p_buf->dscp_info.descriptor.dsc_list = (UINT8 *)(p_buf + 1);
|
||||
memcpy(p_buf->dscp_info.descriptor.dsc_list, dscp_info.descriptor.dsc_list, dscp_info.descriptor.dl_len);
|
||||
} else {
|
||||
p_buf->dscp_info.descriptor.dsc_list = NULL;
|
||||
p_buf->dscp_info.descriptor.dl_len = 0;
|
||||
}
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhRemoveDev
|
||||
**
|
||||
** Description Remove a device from the HID host devices list.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhRemoveDev(UINT8 dev_handle )
|
||||
{
|
||||
tBTA_HH_MAINT_DEV *p_buf;
|
||||
|
||||
p_buf = (tBTA_HH_MAINT_DEV *)GKI_getbuf((UINT16)sizeof(tBTA_HH_MAINT_DEV));
|
||||
|
||||
if (p_buf != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_HH_MAINT_DEV));
|
||||
|
||||
p_buf->hdr.event = BTA_HH_API_MAINT_DEV_EVT;
|
||||
p_buf->sub_event = BTA_HH_RMV_DEV_EVT;
|
||||
p_buf->hdr.layer_specific = (UINT16) dev_handle;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
#if BTA_HH_LE_INCLUDED == TRUE
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhUpdateLeScanParam
|
||||
**
|
||||
** Description Update the scan paramteters if connected to a LE hid device as
|
||||
** report host.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhUpdateLeScanParam(UINT8 dev_handle, UINT16 scan_int, UINT16 scan_win)
|
||||
{
|
||||
tBTA_HH_SCPP_UPDATE *p_buf;
|
||||
|
||||
p_buf = (tBTA_HH_SCPP_UPDATE *)GKI_getbuf((UINT16)sizeof(tBTA_HH_SCPP_UPDATE));
|
||||
|
||||
if (p_buf != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_HH_SCPP_UPDATE));
|
||||
|
||||
p_buf->hdr.event = BTA_HH_API_SCPP_UPDATE_EVT;
|
||||
p_buf->hdr.layer_specific = (UINT16) dev_handle;
|
||||
p_buf->scan_int = scan_int;
|
||||
p_buf->scan_win = scan_win;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*******************************************************************************/
|
||||
/* Utility Function */
|
||||
/*******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhParseBootRpt
|
||||
**
|
||||
** Description This utility function parse a boot mode report.
|
||||
** For keyboard report, report data will carry the keycode max
|
||||
** up to 6 key press in one report. Application need to convert
|
||||
** the keycode into keypress character according to keyboard
|
||||
** language.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhParseBootRpt(tBTA_HH_BOOT_RPT *p_data, UINT8 *p_report,
|
||||
UINT16 report_len)
|
||||
{
|
||||
p_data->dev_type = BTA_HH_DEVT_UNKNOWN;
|
||||
|
||||
if (p_report) {
|
||||
/* first byte is report ID */
|
||||
switch (p_report[0]) {
|
||||
case BTA_HH_KEYBD_RPT_ID: /* key board report ID */
|
||||
p_data->dev_type = p_report[0];
|
||||
bta_hh_parse_keybd_rpt(p_data, p_report + 1, (UINT16)(report_len - 1));
|
||||
break;
|
||||
|
||||
case BTA_HH_MOUSE_RPT_ID: /* mouse report ID */
|
||||
p_data->dev_type = p_report[0];
|
||||
bta_hh_parse_mice_rpt(p_data, p_report + 1, (UINT16)(report_len - 1));
|
||||
break;
|
||||
|
||||
default:
|
||||
APPL_TRACE_DEBUG("Unknown boot report: %d", p_report[0]);;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* BTA_HH_INCLUDED */
|
||||
60
components/bt/bluedroid/bta/hh/bta_hh_cfg.c
Normal file
60
components/bt/bluedroid/bta/hh/bta_hh_cfg.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains compile-time configurable constants for the BTA Hid
|
||||
* Host.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
#include "bta_hh_api.h"
|
||||
|
||||
/* max number of device types supported by BTA */
|
||||
#define BTA_HH_MAX_DEVT_SPT 9
|
||||
|
||||
/* size of database for service discovery */
|
||||
#ifndef BTA_HH_DISC_BUF_SIZE
|
||||
#define BTA_HH_DISC_BUF_SIZE GKI_MAX_BUF_SIZE
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* The type of devices supported by BTA HH and corresponding application ID */
|
||||
tBTA_HH_SPT_TOD p_devt_list[BTA_HH_MAX_DEVT_SPT] = {
|
||||
{BTA_HH_DEVT_MIC, BTA_HH_APP_ID_MI},
|
||||
{BTA_HH_DEVT_KBD, BTA_HH_APP_ID_KB},
|
||||
{BTA_HH_DEVT_KBD | BTA_HH_DEVT_MIC, BTA_HH_APP_ID_KB},
|
||||
{BTA_HH_DEVT_RMC, BTA_HH_APP_ID_RMC},
|
||||
{BTA_HH_DEVT_RMC | BTA_HH_DEVT_KBD, BTA_HH_APP_ID_RMC},
|
||||
{BTA_HH_DEVT_MIC | BTA_HH_DEVT_DGT, BTA_HH_APP_ID_MI},
|
||||
{BTA_HH_DEVT_JOS, BTA_HH_APP_ID_JOY},
|
||||
{BTA_HH_DEVT_GPD, BTA_HH_APP_ID_GPAD},
|
||||
{BTA_HH_DEVT_UNKNOWN, BTA_HH_APP_ID_3DSG}
|
||||
};
|
||||
|
||||
|
||||
const tBTA_HH_CFG bta_hh_cfg = {
|
||||
BTA_HH_MAX_DEVT_SPT, /* number of supported type of devices */
|
||||
p_devt_list, /* ToD & AppID list */
|
||||
BTA_HH_DISC_BUF_SIZE /* HH SDP discovery database size */
|
||||
};
|
||||
|
||||
|
||||
tBTA_HH_CFG *p_bta_hh_cfg = (tBTA_HH_CFG *) &bta_hh_cfg;
|
||||
399
components/bt/bluedroid/bta/hh/bta_hh_int.h
Normal file
399
components/bt/bluedroid/bta/hh/bta_hh_int.h
Normal file
@@ -0,0 +1,399 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains BTA HID Host internal definitions
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef BTA_HH_INT_H
|
||||
#define BTA_HH_INT_H
|
||||
|
||||
#include "bta_sys.h"
|
||||
#include "utl.h"
|
||||
#include "bta_hh_api.h"
|
||||
|
||||
//#if BTA_HH_LE_INCLUDED == TRUE
|
||||
#include "bta_gatt_api.h"
|
||||
//#endif
|
||||
|
||||
/* can be moved to bta_api.h */
|
||||
#define BTA_HH_MAX_RPT_CHARS 8
|
||||
|
||||
#if (BTA_GATT_INCLUDED == FALSE || BLE_INCLUDED == FALSE)
|
||||
#undef BTA_HH_LE_INCLUDED
|
||||
#define BTA_HH_LE_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
/* state machine events, these events are handled by the state machine */
|
||||
enum {
|
||||
BTA_HH_API_OPEN_EVT = BTA_SYS_EVT_START(BTA_ID_HH),
|
||||
BTA_HH_API_CLOSE_EVT,
|
||||
BTA_HH_INT_OPEN_EVT,
|
||||
BTA_HH_INT_CLOSE_EVT,
|
||||
BTA_HH_INT_DATA_EVT,
|
||||
BTA_HH_INT_CTRL_DATA,
|
||||
BTA_HH_INT_HANDSK_EVT,
|
||||
BTA_HH_SDP_CMPL_EVT,
|
||||
BTA_HH_API_WRITE_DEV_EVT,
|
||||
BTA_HH_API_GET_DSCP_EVT,
|
||||
BTA_HH_API_MAINT_DEV_EVT,
|
||||
BTA_HH_OPEN_CMPL_EVT,
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
BTA_HH_GATT_CLOSE_EVT,
|
||||
BTA_HH_GATT_OPEN_EVT,
|
||||
BTA_HH_START_ENC_EVT,
|
||||
BTA_HH_ENC_CMPL_EVT,
|
||||
BTA_HH_GATT_READ_CHAR_CMPL_EVT,
|
||||
BTA_HH_GATT_WRITE_CHAR_CMPL_EVT,
|
||||
BTA_HH_GATT_READ_DESCR_CMPL_EVT,
|
||||
BTA_HH_GATT_WRITE_DESCR_CMPL_EVT,
|
||||
BTA_HH_API_SCPP_UPDATE_EVT,
|
||||
BTA_HH_GATT_ENC_CMPL_EVT,
|
||||
#endif
|
||||
|
||||
/* not handled by execute state machine */
|
||||
BTA_HH_API_ENABLE_EVT,
|
||||
BTA_HH_API_DISABLE_EVT,
|
||||
BTA_HH_DISC_CMPL_EVT
|
||||
};
|
||||
typedef UINT16 tBTA_HH_INT_EVT; /* HID host internal events */
|
||||
|
||||
#define BTA_HH_INVALID_EVT (BTA_HH_DISC_CMPL_EVT + 1)
|
||||
|
||||
/* event used to map between BTE event and BTA event */
|
||||
#define BTA_HH_FST_TRANS_CB_EVT BTA_HH_GET_RPT_EVT
|
||||
#define BTA_HH_FST_BTE_TRANS_EVT HID_TRANS_GET_REPORT
|
||||
|
||||
/* sub event code used for device maintainence API call */
|
||||
#define BTA_HH_ADD_DEV 0
|
||||
#define BTA_HH_REMOVE_DEV 1
|
||||
|
||||
/* state machine states */
|
||||
enum {
|
||||
BTA_HH_NULL_ST,
|
||||
BTA_HH_IDLE_ST,
|
||||
BTA_HH_W4_CONN_ST,
|
||||
BTA_HH_CONN_ST
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
, BTA_HH_W4_SEC
|
||||
#endif
|
||||
, BTA_HH_INVALID_ST /* Used to check invalid states before executing SM function */
|
||||
|
||||
};
|
||||
typedef UINT8 tBTA_HH_STATE;
|
||||
|
||||
/* data structure used to send a command/data to HID device */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT8 t_type;
|
||||
UINT8 param;
|
||||
UINT8 rpt_id;
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
UINT8 srvc_id;
|
||||
#endif
|
||||
UINT16 data;
|
||||
BT_HDR *p_data;
|
||||
} tBTA_HH_CMD_DATA;
|
||||
|
||||
/* data type for BTA_HH_API_ENABLE_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT8 sec_mask;
|
||||
UINT8 service_name[BTA_SERVICE_NAME_LEN + 1];
|
||||
tBTA_HH_CBACK *p_cback;
|
||||
} tBTA_HH_API_ENABLE;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR bd_addr;
|
||||
UINT8 sec_mask;
|
||||
tBTA_HH_PROTO_MODE mode;
|
||||
} tBTA_HH_API_CONN;
|
||||
|
||||
/* internal event data from BTE HID callback */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR addr;
|
||||
UINT32 data;
|
||||
BT_HDR *p_data;
|
||||
} tBTA_HH_CBACK_DATA;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR bda;
|
||||
UINT16 attr_mask;
|
||||
UINT16 sub_event;
|
||||
UINT8 sub_class;
|
||||
UINT8 app_id;
|
||||
tBTA_HH_DEV_DSCP_INFO dscp_info;
|
||||
} tBTA_HH_MAINT_DEV;
|
||||
|
||||
#if BTA_HH_LE_INCLUDED == TRUE
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT16 conn_id;
|
||||
tBTA_GATT_REASON reason; /* disconnect reason code, not useful when connect event is reported */
|
||||
|
||||
} tBTA_HH_LE_CLOSE;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT16 scan_int;
|
||||
UINT16 scan_win;
|
||||
} tBTA_HH_SCPP_UPDATE;
|
||||
#endif
|
||||
/* union of all event data types */
|
||||
typedef union {
|
||||
BT_HDR hdr;
|
||||
tBTA_HH_API_ENABLE api_enable;
|
||||
tBTA_HH_API_CONN api_conn;
|
||||
tBTA_HH_CMD_DATA api_sndcmd;
|
||||
tBTA_HH_CBACK_DATA hid_cback;
|
||||
tBTA_HH_STATUS status;
|
||||
tBTA_HH_MAINT_DEV api_maintdev;
|
||||
#if BTA_HH_LE_INCLUDED == TRUE
|
||||
tBTA_HH_LE_CLOSE le_close;
|
||||
tBTA_GATTC_OPEN le_open;
|
||||
tBTA_HH_SCPP_UPDATE le_scpp_update;
|
||||
tBTA_GATTC_ENC_CMPL_CB le_enc_cmpl;
|
||||
#endif
|
||||
} tBTA_HH_DATA;
|
||||
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
typedef struct {
|
||||
UINT8 index;
|
||||
BOOLEAN in_use;
|
||||
UINT8 inst_id; /* share service instance ID and report instance ID, as
|
||||
hi 4 for service instance ID, low 4 as charatceristic instance ID */
|
||||
tBTA_HH_RPT_TYPE rpt_type;
|
||||
UINT16 uuid;
|
||||
UINT8 prop;
|
||||
UINT8 rpt_id;
|
||||
BOOLEAN client_cfg_exist;
|
||||
UINT16 client_cfg_value;
|
||||
} tBTA_HH_LE_RPT;
|
||||
|
||||
#ifndef BTA_HH_LE_RPT_MAX
|
||||
#define BTA_HH_LE_RPT_MAX 20
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
BOOLEAN in_use;
|
||||
tBTA_HH_LE_RPT report[BTA_HH_LE_RPT_MAX];
|
||||
|
||||
#define BTA_HH_LE_PROTO_MODE_BIT 0x01
|
||||
#define BTA_HH_LE_CP_BIT 0x02
|
||||
UINT8 option_char; /* control point char exisit or not */
|
||||
|
||||
BOOLEAN expl_incl_srvc;
|
||||
UINT8 incl_srvc_inst; /* assuming only one included service : battery service */
|
||||
UINT8 cur_expl_char_idx; /* currently discovering service index */
|
||||
UINT8 *rpt_map;
|
||||
UINT16 ext_rpt_ref;
|
||||
tBTA_HH_DEV_DESCR descriptor;
|
||||
|
||||
} tBTA_HH_LE_HID_SRVC;
|
||||
|
||||
#ifndef BTA_HH_LE_HID_SRVC_MAX
|
||||
#define BTA_HH_LE_HID_SRVC_MAX 1
|
||||
#endif
|
||||
|
||||
/* convert a HID handle to the LE CB index */
|
||||
#define BTA_HH_GET_LE_CB_IDX(x) (((x) >> 4) - 1)
|
||||
/* convert a GATT connection ID to HID device handle, it is the hi 4 bits of a UINT8 */
|
||||
#define BTA_HH_GET_LE_DEV_HDL(x) (UINT8)(((x) + 1) << 4)
|
||||
/* check to see if th edevice handle is a LE device handle */
|
||||
#define BTA_HH_IS_LE_DEV_HDL(x) ((x) & 0xf0)
|
||||
#define BTA_HH_IS_LE_DEV_HDL_VALID(x) (((x)>>4) <= BTA_HH_LE_MAX_KNOWN)
|
||||
#endif
|
||||
|
||||
/* device control block */
|
||||
typedef struct {
|
||||
tBTA_HH_DEV_DSCP_INFO dscp_info; /* report descriptor and DI information */
|
||||
BD_ADDR addr; /* BD-Addr of the HID device */
|
||||
UINT16 attr_mask; /* attribute mask */
|
||||
UINT16 w4_evt; /* W4_handshake event name */
|
||||
UINT8 index; /* index number referenced to handle index */
|
||||
UINT8 sub_class; /* Cod sub class */
|
||||
UINT8 sec_mask; /* security mask */
|
||||
UINT8 app_id; /* application ID for this connection */
|
||||
UINT8 hid_handle; /* device handle : low 4 bits for regular HID: HID_HOST_MAX_DEVICES can not exceed 15;
|
||||
high 4 bits for LE HID: GATT_MAX_PHY_CHANNEL can not exceed 15 */
|
||||
BOOLEAN vp; /* virtually unplug flag */
|
||||
BOOLEAN in_use; /* control block currently in use */
|
||||
BOOLEAN incoming_conn; /* is incoming connection? */
|
||||
UINT8 incoming_hid_handle; /* temporary handle for incoming connection? */
|
||||
BOOLEAN opened; /* TRUE if device successfully opened HID connection */
|
||||
tBTA_HH_PROTO_MODE mode; /* protocol mode */
|
||||
tBTA_HH_STATE state; /* CB state */
|
||||
|
||||
#if (BTA_HH_LE_INCLUDED == TRUE)
|
||||
#define BTA_HH_LE_DISC_NONE 0x00
|
||||
#define BTA_HH_LE_DISC_HIDS 0x01
|
||||
#define BTA_HH_LE_DISC_DIS 0x02
|
||||
#define BTA_HH_LE_DISC_SCPS 0x04
|
||||
|
||||
UINT8 disc_active;
|
||||
tBTA_HH_STATUS status;
|
||||
tBTA_GATT_REASON reason;
|
||||
BOOLEAN is_le_device;
|
||||
tBTA_HH_LE_HID_SRVC hid_srvc[BTA_HH_LE_HID_SRVC_MAX];
|
||||
UINT16 conn_id;
|
||||
BOOLEAN in_bg_conn;
|
||||
UINT8 total_srvc;
|
||||
UINT8 clt_cfg_idx;
|
||||
UINT8 cur_srvc_index; /* currently discovering service index */
|
||||
BOOLEAN scps_supported;
|
||||
|
||||
#define BTA_HH_LE_SCPS_NOTIFY_NONE 0
|
||||
#define BTA_HH_LE_SCPS_NOTIFY_SPT 0x01
|
||||
#define BTA_HH_LE_SCPS_NOTIFY_ENB 0x02
|
||||
UINT8 scps_notify; /* scan refresh supported/notification enabled */
|
||||
#endif
|
||||
|
||||
BOOLEAN security_pending;
|
||||
} tBTA_HH_DEV_CB;
|
||||
|
||||
/* key board parsing control block */
|
||||
typedef struct {
|
||||
BOOLEAN mod_key[4]; /* ctrl, shift(upper), Alt, GUI */
|
||||
BOOLEAN num_lock;
|
||||
BOOLEAN caps_lock;
|
||||
UINT8 last_report[BTA_HH_MAX_RPT_CHARS];
|
||||
} tBTA_HH_KB_CB;
|
||||
|
||||
/******************************************************************************
|
||||
** Main Control Block
|
||||
*******************************************************************************/
|
||||
typedef struct {
|
||||
tBTA_HH_KB_CB kb_cb; /* key board control block,
|
||||
suppose BTA will connect
|
||||
to only one keyboard at
|
||||
the same time */
|
||||
tBTA_HH_DEV_CB kdev[BTA_HH_MAX_DEVICE]; /* device control block */
|
||||
tBTA_HH_DEV_CB *p_cur; /* current device control
|
||||
block idx, used in sdp */
|
||||
UINT8 cb_index[BTA_HH_MAX_KNOWN]; /* maintain a CB index
|
||||
map to dev handle */
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
UINT8 le_cb_index[BTA_HH_MAX_DEVICE]; /* maintain a CB index map to LE dev handle */
|
||||
tBTA_GATTC_IF gatt_if;
|
||||
#endif
|
||||
tBTA_HH_CBACK *p_cback; /* Application callbacks */
|
||||
tSDP_DISCOVERY_DB *p_disc_db;
|
||||
UINT8 trace_level; /* tracing level */
|
||||
UINT8 cnt_num; /* connected device number */
|
||||
BOOLEAN w4_disable; /* w4 disable flag */
|
||||
}
|
||||
tBTA_HH_CB;
|
||||
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
extern tBTA_HH_CB bta_hh_cb;
|
||||
#else
|
||||
extern tBTA_HH_CB *bta_hh_cb_ptr;
|
||||
#define bta_hh_cb (*bta_hh_cb_ptr)
|
||||
#endif
|
||||
|
||||
/* from bta_hh_cfg.c */
|
||||
extern tBTA_HH_CFG *p_bta_hh_cfg;
|
||||
|
||||
/*****************************************************************************
|
||||
** Function prototypes
|
||||
*****************************************************************************/
|
||||
extern BOOLEAN bta_hh_hdl_event(BT_HDR *p_msg);
|
||||
extern void bta_hh_sm_execute(tBTA_HH_DEV_CB *p_cb, UINT16 event,
|
||||
tBTA_HH_DATA *p_data);
|
||||
|
||||
/* action functions */
|
||||
extern void bta_hh_api_disc_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_open_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_close_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_data_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_ctrl_dat_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_start_sdp(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_write_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_get_dscp_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_handsk_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_maint_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_open_cmpl_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_open_failure(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
|
||||
/* utility functions */
|
||||
extern UINT8 bta_hh_find_cb(BD_ADDR bda);
|
||||
extern void bta_hh_parse_keybd_rpt(tBTA_HH_BOOT_RPT *p_kb_data,
|
||||
UINT8 *p_report, UINT16 report_len);
|
||||
extern void bta_hh_parse_mice_rpt(tBTA_HH_BOOT_RPT *p_kb_data,
|
||||
UINT8 *p_report, UINT16 report_len);
|
||||
extern BOOLEAN bta_hh_tod_spt(tBTA_HH_DEV_CB *p_cb, UINT8 sub_class);
|
||||
extern void bta_hh_clean_up_kdev(tBTA_HH_DEV_CB *p_cb);
|
||||
|
||||
extern void bta_hh_add_device_to_list(tBTA_HH_DEV_CB *p_cb, UINT8 handle,
|
||||
UINT16 attr_mask,
|
||||
tHID_DEV_DSCP_INFO *p_dscp_info,
|
||||
UINT8 sub_class, UINT16 max_latency, UINT16 min_tout, UINT8 app_id);
|
||||
extern void bta_hh_update_di_info(tBTA_HH_DEV_CB *p_cb, UINT16 vendor_id, UINT16 product_id,
|
||||
UINT16 version, UINT8 flag);
|
||||
extern void bta_hh_cleanup_disable(tBTA_HH_STATUS status);
|
||||
|
||||
extern UINT8 bta_hh_dev_handle_to_cb_idx(UINT8 dev_handle);
|
||||
|
||||
/* action functions used outside state machine */
|
||||
extern void bta_hh_api_enable(tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_api_disable(void);
|
||||
extern void bta_hh_disc_cmpl(void);
|
||||
|
||||
extern tBTA_HH_STATUS bta_hh_read_ssr_param(BD_ADDR bd_addr, UINT16 *p_max_ssr_lat, UINT16 *p_min_ssr_tout);
|
||||
|
||||
/* functions for LE HID */
|
||||
extern void bta_hh_le_enable(void);
|
||||
extern BOOLEAN bta_hh_le_is_hh_gatt_if(tBTA_GATTC_IF client_if);
|
||||
extern void bta_hh_le_deregister(void);
|
||||
extern BOOLEAN bta_hh_is_le_device(tBTA_HH_DEV_CB *p_cb, BD_ADDR remote_bda);
|
||||
extern void bta_hh_le_open_conn(tBTA_HH_DEV_CB *p_cb, BD_ADDR remote_bda);
|
||||
extern void bta_hh_le_api_disc_act(tBTA_HH_DEV_CB *p_cb);
|
||||
extern void bta_hh_le_get_dscp_act(tBTA_HH_DEV_CB *p_cb);
|
||||
extern void bta_hh_le_write_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern UINT8 bta_hh_le_add_device(tBTA_HH_DEV_CB *p_cb, tBTA_HH_MAINT_DEV *p_dev_info);
|
||||
extern void bta_hh_le_remove_dev_bg_conn(tBTA_HH_DEV_CB *p_cb);
|
||||
extern void bta_hh_le_open_fail(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_gatt_open(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_gatt_close(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_start_security(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_start_srvc_discovery(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_w4_le_read_char_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_le_read_char_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_w4_le_read_descr_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_le_read_descr_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_w4_le_write_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_le_write_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_le_write_char_descr_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_start_security(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_security_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_le_update_scpp(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_le_notify_enc_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_ci_load_rpt (tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
|
||||
#if BTA_HH_DEBUG
|
||||
extern void bta_hh_trace_dev_db(void);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
3024
components/bt/bluedroid/bta/hh/bta_hh_le.c
Normal file
3024
components/bt/bluedroid/bta/hh/bta_hh_le.c
Normal file
File diff suppressed because it is too large
Load Diff
560
components/bt/bluedroid/bta/hh/bta_hh_main.c
Normal file
560
components/bt/bluedroid/bta/hh/bta_hh_main.c
Normal file
@@ -0,0 +1,560 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the HID host main functions and state machine.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
|
||||
#if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "bta_hh_api.h"
|
||||
#include "bta_hh_int.h"
|
||||
#include "gki.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and types
|
||||
*****************************************************************************/
|
||||
|
||||
/* state machine action enumeration list */
|
||||
enum {
|
||||
BTA_HH_API_DISC_ACT, /* HID host process API close action */
|
||||
BTA_HH_OPEN_ACT, /* HID host process BTA_HH_EVT_OPEN */
|
||||
BTA_HH_CLOSE_ACT, /* HID host process BTA_HH_EVT_CLOSE */
|
||||
BTA_HH_DATA_ACT, /* HID host receive data report */
|
||||
BTA_HH_CTRL_DAT_ACT,
|
||||
BTA_HH_HANDSK_ACT,
|
||||
BTA_HH_START_SDP, /* HID host inquery */
|
||||
BTA_HH_SDP_CMPL,
|
||||
BTA_HH_WRITE_DEV_ACT,
|
||||
BTA_HH_GET_DSCP_ACT,
|
||||
BTA_HH_MAINT_DEV_ACT,
|
||||
BTA_HH_OPEN_CMPL_ACT,
|
||||
BTA_HH_OPEN_FAILURE,
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
BTA_HH_GATT_CLOSE,
|
||||
BTA_HH_LE_OPEN_FAIL,
|
||||
BTA_HH_GATT_OPEN,
|
||||
BTA_HH_W4_LE_READ_CHAR,
|
||||
BTA_HH_LE_READ_CHAR,
|
||||
BTA_HH_W4_LE_READ_DESCR,
|
||||
BTA_HH_LE_READ_DESCR,
|
||||
BTA_HH_W4_LE_WRITE,
|
||||
BTA_HH_LE_WRITE,
|
||||
BTA_HH_WRITE_DESCR,
|
||||
BTA_HH_START_SEC,
|
||||
BTA_HH_SEC_CMPL,
|
||||
BTA_HH_LE_UPDATE_SCPP,
|
||||
BTA_HH_GATT_ENC_CMPL,
|
||||
#endif
|
||||
BTA_HH_NUM_ACTIONS
|
||||
};
|
||||
|
||||
#define BTA_HH_IGNORE BTA_HH_NUM_ACTIONS
|
||||
|
||||
/* type for action functions */
|
||||
typedef void (*tBTA_HH_ACTION)(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
|
||||
/* action functions */
|
||||
const tBTA_HH_ACTION bta_hh_action[] = {
|
||||
bta_hh_api_disc_act,
|
||||
bta_hh_open_act,
|
||||
bta_hh_close_act,
|
||||
bta_hh_data_act,
|
||||
bta_hh_ctrl_dat_act,
|
||||
bta_hh_handsk_act,
|
||||
bta_hh_start_sdp,
|
||||
bta_hh_sdp_cmpl,
|
||||
bta_hh_write_dev_act,
|
||||
bta_hh_get_dscp_act,
|
||||
bta_hh_maint_dev_act,
|
||||
bta_hh_open_cmpl_act,
|
||||
bta_hh_open_failure
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
, bta_hh_gatt_close
|
||||
, bta_hh_le_open_fail
|
||||
, bta_hh_gatt_open
|
||||
, bta_hh_w4_le_read_char_cmpl
|
||||
, bta_hh_le_read_char_cmpl
|
||||
, bta_hh_w4_le_read_descr_cmpl
|
||||
, bta_hh_le_read_descr_cmpl
|
||||
, bta_hh_w4_le_write_cmpl
|
||||
, bta_hh_le_write_cmpl
|
||||
, bta_hh_le_write_char_descr_cmpl
|
||||
, bta_hh_start_security
|
||||
, bta_hh_security_cmpl
|
||||
, bta_hh_le_update_scpp
|
||||
, bta_hh_le_notify_enc_cmpl
|
||||
#endif
|
||||
};
|
||||
|
||||
/* state table information */
|
||||
#define BTA_HH_ACTION 0 /* position of action */
|
||||
#define BTA_HH_NEXT_STATE 1 /* position of next state */
|
||||
#define BTA_HH_NUM_COLS 2 /* number of columns */
|
||||
|
||||
/* state table for idle state */
|
||||
const UINT8 bta_hh_st_idle[][BTA_HH_NUM_COLS] = {
|
||||
/* Event Action Next state */
|
||||
/* BTA_HH_API_OPEN_EVT */ {BTA_HH_START_SDP, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_API_CLOSE_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_OPEN_EVT */ {BTA_HH_OPEN_ACT, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_INT_CLOSE_EVT */ {BTA_HH_CLOSE_ACT, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_DATA_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_CTRL_DATA */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_HANDSK_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_SDP_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_API_WRITE_DEV_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_API_GET_DSCP_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_API_MAINT_DEV_EVT */ {BTA_HH_MAINT_DEV_ACT, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_OPEN_CMPL_EVT */ {BTA_HH_OPEN_CMPL_ACT, BTA_HH_CONN_ST }
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
/* BTA_HH_GATT_CLOSE_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* BTA_HH_GATT_OPEN_EVT */ , {BTA_HH_GATT_OPEN, BTA_HH_W4_CONN_ST }
|
||||
/* BTA_HH_START_ENC_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* BTA_HH_ENC_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* READ_CHAR_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* BTA_HH_GATT_WRITE_CMPL_EVT*/ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* READ_DESCR_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* WRITE_DESCR_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* SCPP_UPDATE_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* BTA_HH_GATT_ENC_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
const UINT8 bta_hh_st_w4_conn[][BTA_HH_NUM_COLS] = {
|
||||
/* Event Action Next state */
|
||||
/* BTA_HH_API_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_API_CLOSE_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_OPEN_EVT */ {BTA_HH_OPEN_ACT, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_INT_CLOSE_EVT */ {BTA_HH_OPEN_FAILURE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_DATA_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_INT_CTRL_DATA */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_INT_HANDSK_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_SDP_CMPL_EVT */ {BTA_HH_SDP_CMPL, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_API_WRITE_DEV_EVT */ {BTA_HH_WRITE_DEV_ACT, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_API_GET_DSCP_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_API_MAINT_DEV_EVT */ {BTA_HH_MAINT_DEV_ACT, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_OPEN_CMPL_EVT */ {BTA_HH_OPEN_CMPL_ACT, BTA_HH_CONN_ST }
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
/* BTA_HH_GATT_CLOSE_EVT */ , {BTA_HH_LE_OPEN_FAIL, BTA_HH_IDLE_ST }
|
||||
/* BTA_HH_GATT_OPEN_EVT */ , {BTA_HH_GATT_OPEN, BTA_HH_W4_CONN_ST }
|
||||
/* BTA_HH_START_ENC_EVT */ , {BTA_HH_START_SEC, BTA_HH_W4_SEC }
|
||||
/* BTA_HH_ENC_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST }
|
||||
/* READ_CHAR_CMPL_EVT */ , {BTA_HH_W4_LE_READ_CHAR, BTA_HH_W4_CONN_ST }
|
||||
/* BTA_HH_GATT_WRITE_CMPL_EVT*/ , {BTA_HH_W4_LE_WRITE, BTA_HH_W4_CONN_ST }
|
||||
/* READ_DESCR_CMPL_EVT */ , {BTA_HH_W4_LE_READ_DESCR, BTA_HH_W4_CONN_ST }
|
||||
/* WRITE_DESCR_CMPL_EVT */ , {BTA_HH_WRITE_DESCR, BTA_HH_W4_CONN_ST }
|
||||
/* SCPP_UPDATE_EVT */ , {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST }
|
||||
/* BTA_HH_GATT_ENC_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST }
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
const UINT8 bta_hh_st_connected[][BTA_HH_NUM_COLS] = {
|
||||
/* Event Action Next state */
|
||||
/* BTA_HH_API_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_API_CLOSE_EVT */ {BTA_HH_API_DISC_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_INT_OPEN_EVT */ {BTA_HH_OPEN_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_INT_CLOSE_EVT */ {BTA_HH_CLOSE_ACT, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_DATA_EVT */ {BTA_HH_DATA_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_INT_CTRL_DATA */ {BTA_HH_CTRL_DAT_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_INT_HANDSK_EVT */ {BTA_HH_HANDSK_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_SDP_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_API_WRITE_DEV_EVT */ {BTA_HH_WRITE_DEV_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_API_GET_DSCP_EVT */ {BTA_HH_GET_DSCP_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_API_MAINT_DEV_EVT */ {BTA_HH_MAINT_DEV_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_OPEN_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_CONN_ST }
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
/* BTA_HH_GATT_CLOSE_EVT */ , {BTA_HH_GATT_CLOSE, BTA_HH_IDLE_ST }
|
||||
/* BTA_HH_GATT_OPEN_EVT */ , {BTA_HH_IGNORE, BTA_HH_CONN_ST }
|
||||
/* BTA_HH_START_ENC_EVT */ , {BTA_HH_IGNORE, BTA_HH_CONN_ST }
|
||||
/* BTA_HH_ENC_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_CONN_ST }
|
||||
/* READ_CHAR_CMPL_EVT */ , {BTA_HH_LE_READ_CHAR, BTA_HH_CONN_ST }
|
||||
/* WRITE_CHAR_CMPL_EVT*/ , {BTA_HH_LE_WRITE, BTA_HH_CONN_ST }
|
||||
/* READ_DESCR_CMPL_EVT */ , {BTA_HH_LE_READ_DESCR, BTA_HH_CONN_ST } /* do not currently read any descr when connection up */
|
||||
/* WRITE_DESCR_CMPL_EVT */ , {BTA_HH_WRITE_DESCR, BTA_HH_CONN_ST } /* do not currently write any descr when connection up */
|
||||
/* SCPP_UPDATE_EVT */ , {BTA_HH_LE_UPDATE_SCPP, BTA_HH_CONN_ST }
|
||||
/* BTA_HH_GATT_ENC_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_CONN_ST }
|
||||
#endif
|
||||
};
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
const UINT8 bta_hh_st_w4_sec[][BTA_HH_NUM_COLS] = {
|
||||
/* Event Action Next state */
|
||||
/* BTA_HH_API_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_API_CLOSE_EVT */ {BTA_HH_API_DISC_ACT, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_INT_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_INT_CLOSE_EVT */ {BTA_HH_OPEN_FAILURE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_DATA_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_INT_CTRL_DATA */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_INT_HANDSK_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_SDP_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_API_WRITE_DEV_EVT */ {BTA_HH_IGNORE , BTA_HH_W4_SEC },
|
||||
/* BTA_HH_API_GET_DSCP_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_API_MAINT_DEV_EVT */ {BTA_HH_MAINT_DEV_ACT, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_OPEN_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_GATT_CLOSE_EVT */ {BTA_HH_LE_OPEN_FAIL, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_GATT_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_START_ENC_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_ENC_CMPL_EVT */ {BTA_HH_SEC_CMPL, BTA_HH_W4_CONN_ST },
|
||||
/* READ_CHAR_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_GATT_WRITE_CMPL_EVT*/ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* READ_DESCR_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* WRITE_DESCR_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC }
|
||||
/* SCPP_UPDATE_EVT */ , {BTA_HH_IGNORE, BTA_HH_W4_SEC }
|
||||
/* BTA_HH_GATT_ENC_CMPL_EVT */ , {BTA_HH_GATT_ENC_CMPL, BTA_HH_W4_SEC }
|
||||
};
|
||||
#endif
|
||||
|
||||
/* type for state table */
|
||||
typedef const UINT8 (*tBTA_HH_ST_TBL)[BTA_HH_NUM_COLS];
|
||||
|
||||
/* state table */
|
||||
const tBTA_HH_ST_TBL bta_hh_st_tbl[] = {
|
||||
bta_hh_st_idle,
|
||||
bta_hh_st_w4_conn,
|
||||
bta_hh_st_connected
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
, bta_hh_st_w4_sec
|
||||
#endif
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
** Global data
|
||||
*****************************************************************************/
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
tBTA_HH_CB bta_hh_cb;
|
||||
#endif
|
||||
/*****************************************************************************
|
||||
** Static functions
|
||||
*****************************************************************************/
|
||||
#if BTA_HH_DEBUG == TRUE
|
||||
static char *bta_hh_evt_code(tBTA_HH_INT_EVT evt_code);
|
||||
static char *bta_hh_state_code(tBTA_HH_STATE state_code);
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_sm_execute
|
||||
**
|
||||
** Description State machine event handling function for HID Host
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_sm_execute(tBTA_HH_DEV_CB *p_cb, UINT16 event, tBTA_HH_DATA *p_data)
|
||||
{
|
||||
tBTA_HH_ST_TBL state_table;
|
||||
UINT8 action;
|
||||
tBTA_HH cback_data;
|
||||
tBTA_HH_EVT cback_event = 0;
|
||||
#if BTA_HH_DEBUG == TRUE
|
||||
tBTA_HH_STATE in_state ;
|
||||
UINT16 debug_event = event;
|
||||
#endif
|
||||
|
||||
memset(&cback_data, 0, sizeof(tBTA_HH));
|
||||
|
||||
/* handle exception, no valid control block was found */
|
||||
if (!p_cb) {
|
||||
/* BTA HH enabled already? otherwise ignore the event although it's bad*/
|
||||
if (bta_hh_cb.p_cback != NULL) {
|
||||
switch (event) {
|
||||
/* no control block available for new connection */
|
||||
case BTA_HH_API_OPEN_EVT:
|
||||
cback_event = BTA_HH_OPEN_EVT;
|
||||
/* build cback data */
|
||||
bdcpy(cback_data.conn.bda, ((tBTA_HH_API_CONN *)p_data)->bd_addr);
|
||||
cback_data.conn.status = BTA_HH_ERR_DB_FULL;
|
||||
cback_data.conn.handle = BTA_HH_INVALID_HANDLE;
|
||||
break;
|
||||
/* DB full, BTA_HhAddDev */
|
||||
case BTA_HH_API_MAINT_DEV_EVT:
|
||||
cback_event = p_data->api_maintdev.sub_event;
|
||||
|
||||
if (p_data->api_maintdev.sub_event == BTA_HH_ADD_DEV_EVT) {
|
||||
bdcpy(cback_data.dev_info.bda, p_data->api_maintdev.bda);
|
||||
cback_data.dev_info.status = BTA_HH_ERR_DB_FULL;
|
||||
cback_data.dev_info.handle = BTA_HH_INVALID_HANDLE;
|
||||
} else {
|
||||
cback_data.dev_info.status = BTA_HH_ERR_HDL;
|
||||
cback_data.dev_info.handle = (UINT8)p_data->api_maintdev.hdr.layer_specific;
|
||||
}
|
||||
break;
|
||||
case BTA_HH_API_WRITE_DEV_EVT:
|
||||
cback_event = (p_data->api_sndcmd.t_type - BTA_HH_FST_BTE_TRANS_EVT) +
|
||||
BTA_HH_FST_TRANS_CB_EVT;
|
||||
if (p_data->api_sndcmd.p_data != NULL) {
|
||||
GKI_freebuf(p_data->api_sndcmd.p_data);
|
||||
}
|
||||
if (p_data->api_sndcmd.t_type == HID_TRANS_SET_PROTOCOL ||
|
||||
p_data->api_sndcmd.t_type == HID_TRANS_SET_REPORT ||
|
||||
p_data->api_sndcmd.t_type == HID_TRANS_SET_IDLE) {
|
||||
cback_data.dev_status.status = BTA_HH_ERR_HDL;
|
||||
cback_data.dev_status.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
|
||||
} else if (p_data->api_sndcmd.t_type != HID_TRANS_DATA &&
|
||||
p_data->api_sndcmd.t_type != HID_TRANS_CONTROL) {
|
||||
cback_data.hs_data.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
|
||||
cback_data.hs_data.status = BTA_HH_ERR_HDL;
|
||||
/* hs_data.rsp_data will be all zero, which is not valid value */
|
||||
} else if (p_data->api_sndcmd.t_type == HID_TRANS_CONTROL &&
|
||||
p_data->api_sndcmd.param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG) {
|
||||
cback_data.status = BTA_HH_ERR_HDL;
|
||||
cback_event = BTA_HH_VC_UNPLUG_EVT;
|
||||
} else {
|
||||
cback_event = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case BTA_HH_API_CLOSE_EVT:
|
||||
cback_event = BTA_HH_CLOSE_EVT;
|
||||
|
||||
cback_data.dev_status.status = BTA_HH_ERR_HDL;
|
||||
cback_data.dev_status.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* invalid handle, call bad API event */
|
||||
APPL_TRACE_ERROR("wrong device handle: [%d]", p_data->hdr.layer_specific);
|
||||
/* Free the callback buffer now */
|
||||
if (p_data != NULL && p_data->hid_cback.p_data != NULL) {
|
||||
GKI_freebuf(p_data->hid_cback.p_data);
|
||||
p_data->hid_cback.p_data = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (cback_event) {
|
||||
(* bta_hh_cb.p_cback)(cback_event, &cback_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* corresponding CB is found, go to state machine */
|
||||
else {
|
||||
#if BTA_HH_DEBUG == TRUE
|
||||
in_state = p_cb->state;
|
||||
APPL_TRACE_EVENT("bta_hh_sm_execute: State 0x%02x [%s], Event [%s]",
|
||||
in_state, bta_hh_state_code(in_state),
|
||||
bta_hh_evt_code(debug_event));
|
||||
#endif
|
||||
|
||||
if ((p_cb->state == BTA_HH_NULL_ST) || (p_cb->state >= BTA_HH_INVALID_ST)) {
|
||||
APPL_TRACE_ERROR("bta_hh_sm_execute: Invalid state State = 0x%x, Event = %d",
|
||||
p_cb->state, event);
|
||||
return;
|
||||
}
|
||||
state_table = bta_hh_st_tbl[p_cb->state - 1];
|
||||
|
||||
event &= 0xff;
|
||||
|
||||
p_cb->state = state_table[event][BTA_HH_NEXT_STATE] ;
|
||||
|
||||
if ((action = state_table[event][BTA_HH_ACTION]) != BTA_HH_IGNORE) {
|
||||
(*bta_hh_action[action])(p_cb, p_data);
|
||||
}
|
||||
|
||||
#if BTA_HH_DEBUG == TRUE
|
||||
if (in_state != p_cb->state) {
|
||||
APPL_TRACE_DEBUG("HH State Change: [%s] -> [%s] after Event [%s]",
|
||||
bta_hh_state_code(in_state),
|
||||
bta_hh_state_code(p_cb->state),
|
||||
bta_hh_evt_code(debug_event));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_hdl_event
|
||||
**
|
||||
** Description HID host main event handling function.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_hh_hdl_event(BT_HDR *p_msg)
|
||||
{
|
||||
UINT8 index = BTA_HH_IDX_INVALID;
|
||||
tBTA_HH_DEV_CB *p_cb = NULL;
|
||||
|
||||
switch (p_msg->event) {
|
||||
case BTA_HH_API_ENABLE_EVT:
|
||||
bta_hh_api_enable((tBTA_HH_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_HH_API_DISABLE_EVT:
|
||||
bta_hh_api_disable();
|
||||
break;
|
||||
|
||||
case BTA_HH_DISC_CMPL_EVT: /* disable complete */
|
||||
bta_hh_disc_cmpl();
|
||||
break;
|
||||
|
||||
default:
|
||||
/* all events processed in state machine need to find corresponding
|
||||
CB before proceed */
|
||||
if (p_msg->event == BTA_HH_API_OPEN_EVT) {
|
||||
index = bta_hh_find_cb(((tBTA_HH_API_CONN *)p_msg)->bd_addr);
|
||||
} else if (p_msg->event == BTA_HH_API_MAINT_DEV_EVT) {
|
||||
/* if add device */
|
||||
if (((tBTA_HH_MAINT_DEV *)p_msg)->sub_event == BTA_HH_ADD_DEV_EVT) {
|
||||
index = bta_hh_find_cb(((tBTA_HH_MAINT_DEV *)p_msg)->bda);
|
||||
} else { /* else remove device by handle */
|
||||
index = bta_hh_dev_handle_to_cb_idx((UINT8)p_msg->layer_specific);
|
||||
// btla-specific ++
|
||||
/* If BT disable is done while the HID device is connected and Link_Key uses unauthenticated combination
|
||||
* then we can get into a situation where remove_bonding is called with the index set to 0 (without getting
|
||||
* cleaned up). Only when VIRTUAL_UNPLUG is called do we cleanup the index and make it MAX_KNOWN.
|
||||
* So if REMOVE_DEVICE is called and in_use is FALSE then we should treat this as a NULL p_cb. Hence we
|
||||
* force the index to be IDX_INVALID
|
||||
*/
|
||||
if ((index != BTA_HH_IDX_INVALID) &&
|
||||
(bta_hh_cb.kdev[index].in_use == FALSE)) {
|
||||
index = BTA_HH_IDX_INVALID;
|
||||
}
|
||||
// btla-specific --
|
||||
}
|
||||
} else if (p_msg->event == BTA_HH_INT_OPEN_EVT) {
|
||||
index = bta_hh_find_cb(((tBTA_HH_CBACK_DATA *)p_msg)->addr);
|
||||
} else {
|
||||
index = bta_hh_dev_handle_to_cb_idx((UINT8)p_msg->layer_specific);
|
||||
}
|
||||
|
||||
if (index != BTA_HH_IDX_INVALID) {
|
||||
p_cb = &bta_hh_cb.kdev[index];
|
||||
}
|
||||
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("bta_hh_hdl_event:: handle = %d dev_cb[%d] ", p_msg->layer_specific, index);
|
||||
#endif
|
||||
bta_hh_sm_execute(p_cb, p_msg->event, (tBTA_HH_DATA *) p_msg);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
** Debug Functions
|
||||
*****************************************************************************/
|
||||
#if BTA_HH_DEBUG
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_evt_code
|
||||
**
|
||||
** Description
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static char *bta_hh_evt_code(tBTA_HH_INT_EVT evt_code)
|
||||
{
|
||||
switch (evt_code) {
|
||||
case BTA_HH_API_DISABLE_EVT:
|
||||
return "BTA_HH_API_DISABLE_EVT";
|
||||
case BTA_HH_API_ENABLE_EVT:
|
||||
return "BTA_HH_API_ENABLE_EVT";
|
||||
case BTA_HH_API_OPEN_EVT:
|
||||
return "BTA_HH_API_OPEN_EVT";
|
||||
case BTA_HH_API_CLOSE_EVT:
|
||||
return "BTA_HH_API_CLOSE_EVT";
|
||||
case BTA_HH_INT_OPEN_EVT:
|
||||
return "BTA_HH_INT_OPEN_EVT";
|
||||
case BTA_HH_INT_CLOSE_EVT:
|
||||
return "BTA_HH_INT_CLOSE_EVT";
|
||||
case BTA_HH_INT_HANDSK_EVT:
|
||||
return "BTA_HH_INT_HANDSK_EVT";
|
||||
case BTA_HH_INT_DATA_EVT:
|
||||
return "BTA_HH_INT_DATA_EVT";
|
||||
case BTA_HH_INT_CTRL_DATA:
|
||||
return "BTA_HH_INT_CTRL_DATA";
|
||||
case BTA_HH_API_WRITE_DEV_EVT:
|
||||
return "BTA_HH_API_WRITE_DEV_EVT";
|
||||
case BTA_HH_SDP_CMPL_EVT:
|
||||
return "BTA_HH_SDP_CMPL_EVT";
|
||||
case BTA_HH_DISC_CMPL_EVT:
|
||||
return "BTA_HH_DISC_CMPL_EVT";
|
||||
case BTA_HH_API_MAINT_DEV_EVT:
|
||||
return "BTA_HH_API_MAINT_DEV_EVT";
|
||||
case BTA_HH_API_GET_DSCP_EVT:
|
||||
return "BTA_HH_API_GET_DSCP_EVT";
|
||||
case BTA_HH_OPEN_CMPL_EVT:
|
||||
return "BTA_HH_OPEN_CMPL_EVT";
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
case BTA_HH_GATT_CLOSE_EVT:
|
||||
return "BTA_HH_GATT_CLOSE_EVT";
|
||||
case BTA_HH_GATT_OPEN_EVT:
|
||||
return "BTA_HH_GATT_OPEN_EVT";
|
||||
case BTA_HH_START_ENC_EVT:
|
||||
return "BTA_HH_START_ENC_EVT";
|
||||
case BTA_HH_ENC_CMPL_EVT:
|
||||
return "BTA_HH_ENC_CMPL_EVT";
|
||||
case BTA_HH_GATT_READ_CHAR_CMPL_EVT:
|
||||
return "BTA_HH_GATT_READ_CHAR_CMPL_EVT";
|
||||
case BTA_HH_GATT_WRITE_CHAR_CMPL_EVT:
|
||||
return "BTA_HH_GATT_WRITE_CHAR_CMPL_EVT";
|
||||
case BTA_HH_GATT_READ_DESCR_CMPL_EVT:
|
||||
return "BTA_HH_GATT_READ_DESCR_CMPL_EVT";
|
||||
case BTA_HH_GATT_WRITE_DESCR_CMPL_EVT:
|
||||
return "BTA_HH_GATT_WRITE_DESCR_CMPL_EVT";
|
||||
#endif
|
||||
default:
|
||||
return "unknown HID Host event code";
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_state_code
|
||||
**
|
||||
** Description get string representation of HID host state code.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static char *bta_hh_state_code(tBTA_HH_STATE state_code)
|
||||
{
|
||||
switch (state_code) {
|
||||
case BTA_HH_NULL_ST:
|
||||
return"BTA_HH_NULL_ST";
|
||||
case BTA_HH_IDLE_ST:
|
||||
return "BTA_HH_IDLE_ST";
|
||||
case BTA_HH_W4_CONN_ST:
|
||||
return "BTA_HH_W4_CONN_ST";
|
||||
case BTA_HH_CONN_ST:
|
||||
return "BTA_HH_CONN_ST";
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
case BTA_HH_W4_SEC:
|
||||
return "BTA_HH_W4_SEC";
|
||||
#endif
|
||||
default:
|
||||
return "unknown HID Host state";
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Debug Functions */
|
||||
|
||||
#endif /* BTA_HH_INCLUDED */
|
||||
524
components/bt/bluedroid/bta/hh/bta_hh_utils.c
Normal file
524
components/bt/bluedroid/bta/hh/bta_hh_utils.c
Normal file
@@ -0,0 +1,524 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* 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 <string.h>
|
||||
|
||||
#include "bt_target.h"
|
||||
#if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
|
||||
|
||||
|
||||
#include "bta_hh_int.h"
|
||||
|
||||
/* if SSR max latency is not defined by remote device, set the default value
|
||||
as half of the link supervision timeout */
|
||||
#define BTA_HH_GET_DEF_SSR_MAX_LAT(x) ((x)>> 1)
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
#define BTA_HH_KB_CTRL_MASK 0x11
|
||||
#define BTA_HH_KB_SHIFT_MASK 0x22
|
||||
#define BTA_HH_KB_ALT_MASK 0x44
|
||||
#define BTA_HH_KB_GUI_MASK 0x88
|
||||
|
||||
#define BTA_HH_KB_CAPS_LOCK 0x39 /* caps lock */
|
||||
#define BTA_HH_KB_NUM_LOCK 0x53 /* num lock */
|
||||
|
||||
|
||||
#define BTA_HH_MAX_RPT_CHARS 8
|
||||
|
||||
static const UINT8 bta_hh_mod_key_mask[BTA_HH_MOD_MAX_KEY] = {
|
||||
BTA_HH_KB_CTRL_MASK,
|
||||
BTA_HH_KB_SHIFT_MASK,
|
||||
BTA_HH_KB_ALT_MASK,
|
||||
BTA_HH_KB_GUI_MASK
|
||||
};
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_find_cb
|
||||
**
|
||||
** Description Find best available control block according to BD address.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT8 bta_hh_find_cb(BD_ADDR bda)
|
||||
{
|
||||
UINT8 xx;
|
||||
|
||||
/* See how many active devices there are. */
|
||||
for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
|
||||
/* check if any active/known devices is a match */
|
||||
if ((!bdcmp (bda, bta_hh_cb.kdev[xx].addr) &&
|
||||
bdcmp(bda, bd_addr_null) != 0) ) {
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("found kdev_cb[%d] hid_handle = %d ", xx,
|
||||
bta_hh_cb.kdev[xx].hid_handle)
|
||||
#endif
|
||||
return xx;
|
||||
}
|
||||
#if BTA_HH_DEBUG
|
||||
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
|
||||
}
|
||||
|
||||
/* if no active device match, find a spot for it */
|
||||
for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
|
||||
if (!bta_hh_cb.kdev[xx].in_use) {
|
||||
bdcpy(bta_hh_cb.kdev[xx].addr, bda);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* If device list full, report BTA_HH_IDX_INVALID */
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("bta_hh_find_cb:: index = %d while max = %d",
|
||||
xx, BTA_HH_MAX_DEVICE);
|
||||
#endif
|
||||
|
||||
if (xx == BTA_HH_MAX_DEVICE) {
|
||||
xx = BTA_HH_IDX_INVALID;
|
||||
}
|
||||
|
||||
return xx;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_clean_up_kdev
|
||||
**
|
||||
** Description Clean up device control block when device is removed from
|
||||
** manitainace list, and update control block index map.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_clean_up_kdev(tBTA_HH_DEV_CB *p_cb)
|
||||
{
|
||||
UINT8 index;
|
||||
|
||||
if (p_cb->hid_handle != BTA_HH_INVALID_HANDLE ) {
|
||||
#if BTA_HH_LE_INCLUDED == TRUE
|
||||
if (p_cb->is_le_device) {
|
||||
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 */
|
||||
index = p_cb->index; /* Preserve index for this control block */
|
||||
|
||||
/* Free buffer for report descriptor info */
|
||||
utl_freebuf((void **)&p_cb->dscp_info.descriptor.dsc_list);
|
||||
|
||||
memset(p_cb, 0, sizeof (tBTA_HH_DEV_CB)); /* Reset control block */
|
||||
|
||||
p_cb->index = index; /* Restore index for this control block */
|
||||
p_cb->state = BTA_HH_IDLE_ST;
|
||||
p_cb->hid_handle = BTA_HH_INVALID_HANDLE;
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_update_di_info
|
||||
**
|
||||
** Description Maintain a known device list for BTA HH.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_update_di_info(tBTA_HH_DEV_CB *p_cb, UINT16 vendor_id, UINT16 product_id,
|
||||
UINT16 version, UINT8 flag)
|
||||
{
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("vendor_id = 0x%2x product_id = 0x%2x version = 0x%2x",
|
||||
vendor_id, product_id, version);
|
||||
#endif
|
||||
p_cb->dscp_info.vendor_id = vendor_id;
|
||||
p_cb->dscp_info.product_id = product_id;
|
||||
p_cb->dscp_info.version = version;
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
p_cb->dscp_info.flag = flag;
|
||||
#else
|
||||
UNUSED(flag);
|
||||
#endif
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_add_device_to_list
|
||||
**
|
||||
** Description Maintain a known device list for BTA HH.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_add_device_to_list(tBTA_HH_DEV_CB *p_cb, UINT8 handle,
|
||||
UINT16 attr_mask,
|
||||
tHID_DEV_DSCP_INFO *p_dscp_info,
|
||||
UINT8 sub_class,
|
||||
UINT16 ssr_max_latency,
|
||||
UINT16 ssr_min_tout,
|
||||
UINT8 app_id)
|
||||
{
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("subclass = 0x%2x", sub_class);
|
||||
#endif
|
||||
|
||||
p_cb->hid_handle = handle;
|
||||
p_cb->in_use = TRUE;
|
||||
p_cb->attr_mask = attr_mask;
|
||||
|
||||
p_cb->sub_class = sub_class;
|
||||
p_cb->app_id = app_id;
|
||||
|
||||
p_cb->dscp_info.ssr_max_latency = ssr_max_latency;
|
||||
p_cb->dscp_info.ssr_min_tout = ssr_min_tout;
|
||||
|
||||
/* store report descriptor info */
|
||||
if ( p_dscp_info) {
|
||||
utl_freebuf((void **)&p_cb->dscp_info.descriptor.dsc_list);
|
||||
|
||||
if (p_dscp_info->dl_len &&
|
||||
(p_cb->dscp_info.descriptor.dsc_list =
|
||||
(UINT8 *)GKI_getbuf(p_dscp_info->dl_len)) != NULL) {
|
||||
p_cb->dscp_info.descriptor.dl_len = p_dscp_info->dl_len;
|
||||
memcpy(p_cb->dscp_info.descriptor.dsc_list, p_dscp_info->dsc_list,
|
||||
p_dscp_info->dl_len);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_tod_spt
|
||||
**
|
||||
** Description Check to see if this type of device is supported
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_hh_tod_spt(tBTA_HH_DEV_CB *p_cb, UINT8 sub_class)
|
||||
{
|
||||
UINT8 xx;
|
||||
UINT8 cod = (sub_class >> 2); /* lower two bits are reserved */
|
||||
|
||||
for (xx = 0 ; xx < p_bta_hh_cfg->max_devt_spt; xx ++) {
|
||||
if (cod == (UINT8) p_bta_hh_cfg->p_devt_list[xx].tod) {
|
||||
p_cb->app_id = p_bta_hh_cfg->p_devt_list[xx].app_id;
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_EVENT("bta_hh_tod_spt sub_class:0x%x supported", sub_class);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_EVENT("bta_hh_tod_spt sub_class:0x%x NOT supported", sub_class);
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_parse_keybd_rpt
|
||||
**
|
||||
** Description This utility function parse a boot mode keyboard report.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_parse_keybd_rpt(tBTA_HH_BOOT_RPT *p_kb_data, UINT8 *p_report,
|
||||
UINT16 report_len)
|
||||
{
|
||||
tBTA_HH_KB_CB *p_kb = &bta_hh_cb.kb_cb;
|
||||
tBTA_HH_KEYBD_RPT *p_data = &p_kb_data->data_rpt.keybd_rpt;
|
||||
|
||||
UINT8 this_char, ctl_shift;
|
||||
UINT16 xx, yy, key_idx = 0;
|
||||
UINT8 this_report[BTA_HH_MAX_RPT_CHARS];
|
||||
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("bta_hh_parse_keybd_rpt: (report=%p, report_len=%d) called",
|
||||
p_report, report_len);
|
||||
#endif
|
||||
|
||||
if (report_len < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctl_shift = *p_report++;
|
||||
report_len--;
|
||||
|
||||
if (report_len > BTA_HH_MAX_RPT_CHARS) {
|
||||
report_len = BTA_HH_MAX_RPT_CHARS;
|
||||
}
|
||||
|
||||
memset (this_report, 0, BTA_HH_MAX_RPT_CHARS);
|
||||
memset (p_data, 0, sizeof(tBTA_HH_KEYBD_RPT));
|
||||
memcpy (this_report, p_report, report_len);
|
||||
|
||||
/* Take care of shift, control, GUI and alt, modifier keys */
|
||||
for (xx = 0; xx < BTA_HH_MOD_MAX_KEY; xx ++ ) {
|
||||
if (ctl_shift & bta_hh_mod_key_mask[xx]) {
|
||||
APPL_TRACE_DEBUG("Mod Key[%02x] pressed", bta_hh_mod_key_mask[xx] );
|
||||
p_kb->mod_key[xx] = TRUE;
|
||||
} else if (p_kb->mod_key[xx]) {
|
||||
p_kb->mod_key[xx] = FALSE;
|
||||
}
|
||||
/* control key flag is set */
|
||||
p_data->mod_key[xx] = p_kb->mod_key[xx];
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* First step is to remove all characters we saw in the last report */
|
||||
/***************************************************************************/
|
||||
for (xx = 0; xx < report_len; xx++) {
|
||||
for (yy = 0; yy < BTA_HH_MAX_RPT_CHARS; yy++) {
|
||||
if (this_report[xx] == p_kb->last_report[yy]) {
|
||||
this_report[xx] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/***************************************************************************/
|
||||
/* Now, process all the characters in the report, up to 6 keycodes */
|
||||
/***************************************************************************/
|
||||
for (xx = 0; xx < report_len; xx++) {
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("this_char = %02x", this_report[xx]);
|
||||
#endif
|
||||
if ((this_char = this_report[xx]) == 0) {
|
||||
continue;
|
||||
}
|
||||
/* take the key code as the report data */
|
||||
if (this_report[xx] == BTA_HH_KB_CAPS_LOCK) {
|
||||
p_kb->caps_lock = p_kb->caps_lock ? FALSE : TRUE;
|
||||
} else if (this_report[xx] == BTA_HH_KB_NUM_LOCK) {
|
||||
p_kb->num_lock = p_kb->num_lock ? FALSE : TRUE;
|
||||
} else {
|
||||
p_data->this_char[key_idx ++] = this_char;
|
||||
}
|
||||
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("found keycode %02x ", this_report[xx]);
|
||||
#endif
|
||||
p_data->caps_lock = p_kb->caps_lock;
|
||||
p_data->num_lock = p_kb->num_lock;
|
||||
}
|
||||
|
||||
memset (p_kb->last_report, 0, BTA_HH_MAX_RPT_CHARS);
|
||||
memcpy (p_kb->last_report, p_report, report_len);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_parse_mice_rpt
|
||||
**
|
||||
** Description This utility function parse a boot mode mouse report.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_parse_mice_rpt(tBTA_HH_BOOT_RPT *p_mice_data, UINT8 *p_report,
|
||||
UINT16 report_len)
|
||||
{
|
||||
tBTA_HH_MICE_RPT *p_data = &p_mice_data->data_rpt.mice_rpt;
|
||||
#if BTA_HH_DEBUG
|
||||
UINT8 xx;
|
||||
|
||||
APPL_TRACE_DEBUG("bta_hh_parse_mice_rpt: bta_keybd_rpt_rcvd(report=%p, \
|
||||
report_len=%d) called", p_report, report_len);
|
||||
#endif
|
||||
|
||||
if (report_len < 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (report_len > BTA_HH_MAX_RPT_CHARS) {
|
||||
report_len = BTA_HH_MAX_RPT_CHARS;
|
||||
}
|
||||
|
||||
#if BTA_HH_DEBUG
|
||||
for (xx = 0; xx < report_len; xx++) {
|
||||
APPL_TRACE_DEBUG("this_char = %02x", p_report[xx]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* only first bytes lower 3 bits valid */
|
||||
p_data->mouse_button = (p_report[0] & 0x07);
|
||||
|
||||
/* x displacement */
|
||||
p_data->delta_x = p_report[1];
|
||||
|
||||
/* y displacement */
|
||||
p_data->delta_y = p_report[2];
|
||||
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("mice button: 0x%2x", p_data->mouse_button);
|
||||
APPL_TRACE_DEBUG("mice move: x = %d y = %d", p_data->delta_x,
|
||||
p_data->delta_y );
|
||||
#endif
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_read_ssr_param
|
||||
**
|
||||
** Description Read the SSR Parameter for the remote device
|
||||
**
|
||||
** Returns tBTA_HH_STATUS operation status
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_HH_STATUS bta_hh_read_ssr_param(BD_ADDR bd_addr, UINT16 *p_max_ssr_lat, UINT16 *p_min_ssr_tout)
|
||||
{
|
||||
tBTA_HH_STATUS status = BTA_HH_ERR;
|
||||
tBTA_HH_CB *p_cb = &bta_hh_cb;
|
||||
UINT8 i;
|
||||
UINT16 ssr_max_latency;
|
||||
for (i = 0; i < BTA_HH_MAX_KNOWN; i ++) {
|
||||
if (memcmp(p_cb->kdev[i].addr, bd_addr, BD_ADDR_LEN) == 0) {
|
||||
|
||||
/* if remote device does not have HIDSSRHostMaxLatency attribute in SDP,
|
||||
set SSR max latency default value here. */
|
||||
if (p_cb->kdev[i].dscp_info.ssr_max_latency == HID_SSR_PARAM_INVALID) {
|
||||
/* The default is calculated as half of link supervision timeout.*/
|
||||
|
||||
BTM_GetLinkSuperTout(p_cb->kdev[i].addr, &ssr_max_latency) ;
|
||||
ssr_max_latency = BTA_HH_GET_DEF_SSR_MAX_LAT(ssr_max_latency);
|
||||
|
||||
/* per 1.1 spec, if the newly calculated max latency is greater than
|
||||
BTA_HH_SSR_MAX_LATENCY_DEF which is 500ms, use BTA_HH_SSR_MAX_LATENCY_DEF */
|
||||
if (ssr_max_latency > BTA_HH_SSR_MAX_LATENCY_DEF) {
|
||||
ssr_max_latency = BTA_HH_SSR_MAX_LATENCY_DEF;
|
||||
}
|
||||
|
||||
* p_max_ssr_lat = ssr_max_latency;
|
||||
} else {
|
||||
* p_max_ssr_lat = p_cb->kdev[i].dscp_info.ssr_max_latency;
|
||||
}
|
||||
|
||||
if (p_cb->kdev[i].dscp_info.ssr_min_tout == HID_SSR_PARAM_INVALID) {
|
||||
* p_min_ssr_tout = BTA_HH_SSR_MIN_TOUT_DEF;
|
||||
} else {
|
||||
* p_min_ssr_tout = p_cb->kdev[i].dscp_info.ssr_min_tout;
|
||||
}
|
||||
|
||||
status = BTA_HH_OK;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_cleanup_disable
|
||||
**
|
||||
** Description when disable finished, cleanup control block and send callback
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_cleanup_disable(tBTA_HH_STATUS status)
|
||||
{
|
||||
UINT8 xx;
|
||||
/* free buffer in CB holding report descriptors */
|
||||
for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx ++) {
|
||||
utl_freebuf((void **)&bta_hh_cb.kdev[xx].dscp_info.descriptor.dsc_list);
|
||||
}
|
||||
utl_freebuf((void **)&bta_hh_cb.p_disc_db);
|
||||
|
||||
(* bta_hh_cb.p_cback)(BTA_HH_DISABLE_EVT, (tBTA_HH *)&status);
|
||||
/* all connections are down, no waiting for diconnect */
|
||||
memset(&bta_hh_cb, 0, sizeof(tBTA_HH_CB));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_dev_handle_to_cb_idx
|
||||
**
|
||||
** Description convert a HID device handle to the device control block index.
|
||||
**
|
||||
**
|
||||
** Returns UINT8: index of the device control block.
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT8 bta_hh_dev_handle_to_cb_idx(UINT8 dev_handle)
|
||||
{
|
||||
UINT8 index = BTA_HH_IDX_INVALID;
|
||||
|
||||
#if BTA_HH_LE_INCLUDED == TRUE
|
||||
if (BTA_HH_IS_LE_DEV_HDL(dev_handle)) {
|
||||
if (BTA_HH_IS_LE_DEV_HDL_VALID(dev_handle)) {
|
||||
index = bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(dev_handle)];
|
||||
}
|
||||
#if BTA_HH_DEBUG == TRUE
|
||||
APPL_TRACE_DEBUG("bta_hh_dev_handle_to_cb_idx dev_handle = %d index = %d", dev_handle, index);
|
||||
#endif
|
||||
} else
|
||||
#endif
|
||||
/* regular HID device checking */
|
||||
if (dev_handle < BTA_HH_MAX_KNOWN ) {
|
||||
index = bta_hh_cb.cb_index[dev_handle];
|
||||
}
|
||||
|
||||
return index;
|
||||
|
||||
}
|
||||
#if BTA_HH_DEBUG
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_trace_dev_db
|
||||
**
|
||||
** Description Check to see if this type of device is supported
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_trace_dev_db(void)
|
||||
{
|
||||
UINT8 xx;
|
||||
|
||||
APPL_TRACE_DEBUG("bta_hh_trace_dev_db:: Device DB list********************");
|
||||
|
||||
for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
|
||||
APPL_TRACE_DEBUG("kdev[%d] in_use[%d] handle[%d] ", xx,
|
||||
bta_hh_cb.kdev[xx].in_use, bta_hh_cb.kdev[xx].hid_handle);
|
||||
|
||||
APPL_TRACE_DEBUG("\t\t\t attr_mask[%04x] state [%d] sub_class[%02x] index = %d",
|
||||
bta_hh_cb.kdev[xx].attr_mask, bta_hh_cb.kdev[xx].state,
|
||||
bta_hh_cb.kdev[xx].sub_class, bta_hh_cb.kdev[xx].index);
|
||||
}
|
||||
APPL_TRACE_DEBUG("*********************************************************");
|
||||
}
|
||||
#endif
|
||||
#endif /* HL_INCLUDED */
|
||||
2404
components/bt/bluedroid/bta/include/bta_api.h
Normal file
2404
components/bt/bluedroid/bta/include/bta_api.h
Normal file
File diff suppressed because it is too large
Load Diff
80
components/bt/bluedroid/bta/include/bta_dm_ci.h
Normal file
80
components/bt/bluedroid/bta/include/bta_dm_ci.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2006-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the interface file for device mananger call-in functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_DM_CI_H
|
||||
#define BTA_DM_CI_H
|
||||
|
||||
#include "bta_api.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Function Declarations
|
||||
*****************************************************************************/
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_ci_io_req
|
||||
**
|
||||
** Description This function must be called in response to function
|
||||
** bta_dm_co_io_req(), if *p_oob_data is set to BTA_OOB_UNKNOWN
|
||||
** by bta_dm_co_io_req().
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_ci_io_req(BD_ADDR bd_addr, tBTA_IO_CAP io_cap,
|
||||
tBTA_OOB_DATA oob_data, tBTA_AUTH_REQ auth_req);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_ci_rmt_oob
|
||||
**
|
||||
** Description This function must be called in response to function
|
||||
** bta_dm_co_rmt_oob() to provide the OOB data associated
|
||||
** with the remote device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_ci_rmt_oob(BOOLEAN accept, BD_ADDR bd_addr,
|
||||
BT_OCTET16 c, BT_OCTET16 r);
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sco_ci_data_ready
|
||||
**
|
||||
** Description This function sends an event to indicating that the phone
|
||||
** has SCO data ready..
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_sco_ci_data_ready(UINT16 event, UINT16 sco_handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
273
components/bt/bluedroid/bta/include/bta_dm_co.h
Normal file
273
components/bt/bluedroid/bta/include/bta_dm_co.h
Normal file
@@ -0,0 +1,273 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2006-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the interface file for device mananger callout functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_DM_CO_H
|
||||
#define BTA_DM_CO_H
|
||||
|
||||
#include "bta_sys.h"
|
||||
|
||||
|
||||
#ifndef BTA_SCO_OUT_PKT_SIZE
|
||||
#define BTA_SCO_OUT_PKT_SIZE BTM_SCO_DATA_SIZE_MAX
|
||||
#endif
|
||||
|
||||
#define BTA_SCO_CODEC_PCM 0 /* used for regular SCO */
|
||||
#define BTA_SCO_CODEC_SBC 1 /* used for WBS */
|
||||
typedef UINT8 tBTA_SCO_CODEC_TYPE;
|
||||
|
||||
#define BTA_DM_SCO_SAMP_RATE_8K 8000
|
||||
#define BTA_DM_SCO_SAMP_RATE_16K 16000
|
||||
|
||||
/* SCO codec information */
|
||||
typedef struct {
|
||||
tBTA_SCO_CODEC_TYPE codec_type;
|
||||
} tBTA_CODEC_INFO;
|
||||
|
||||
#define BTA_DM_SCO_ROUTE_PCM BTM_SCO_ROUTE_PCM
|
||||
#define BTA_DM_SCO_ROUTE_HCI BTM_SCO_ROUTE_HCI
|
||||
|
||||
typedef tBTM_SCO_ROUTE_TYPE tBTA_DM_SCO_ROUTE_TYPE;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Function Declarations
|
||||
*****************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_co_io_req
|
||||
**
|
||||
** Description This callout function is executed by DM to get IO capabilities
|
||||
** of the local device for the Simple Pairing process
|
||||
**
|
||||
** Parameters bd_addr - The peer device
|
||||
** *p_io_cap - The local Input/Output capabilities
|
||||
** *p_oob_data - TRUE, if OOB data is available for the peer device.
|
||||
** *p_auth_req - TRUE, if MITM protection is required.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_co_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap,
|
||||
tBTA_OOB_DATA *p_oob_data, tBTA_AUTH_REQ *p_auth_req,
|
||||
BOOLEAN is_orig);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_co_io_rsp
|
||||
**
|
||||
** Description This callout function is executed by DM to report IO capabilities
|
||||
** of the peer device for the Simple Pairing process
|
||||
**
|
||||
** Parameters bd_addr - The peer device
|
||||
** io_cap - The remote Input/Output capabilities
|
||||
** oob_data - TRUE, if OOB data is available for the peer device.
|
||||
** auth_req - TRUE, if MITM protection is required.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_co_io_rsp(BD_ADDR bd_addr, tBTA_IO_CAP io_cap,
|
||||
tBTA_OOB_DATA oob_data, tBTA_AUTH_REQ auth_req);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_co_lk_upgrade
|
||||
**
|
||||
** Description This callout function is executed by DM to check if the
|
||||
** platform wants allow link key upgrade
|
||||
**
|
||||
** Parameters bd_addr - The peer device
|
||||
** *p_upgrade - TRUE, if link key upgrade is desired.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_co_lk_upgrade(BD_ADDR bd_addr, BOOLEAN *p_upgrade );
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_co_loc_oob
|
||||
**
|
||||
** Description This callout function is executed by DM to report the OOB
|
||||
** data of the local device for the Simple Pairing process
|
||||
**
|
||||
** Parameters valid - TRUE, if the local OOB data is retrieved from LM
|
||||
** c - Simple Pairing Hash C
|
||||
** r - Simple Pairing Randomnizer R
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_co_loc_oob(BOOLEAN valid, BT_OCTET16 c, BT_OCTET16 r);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_co_rmt_oob
|
||||
**
|
||||
** Description This callout function is executed by DM to request the OOB
|
||||
** data for the remote device for the Simple Pairing process
|
||||
**
|
||||
** Parameters bd_addr - The peer device
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_co_rmt_oob(BD_ADDR bd_addr);
|
||||
|
||||
/*****************************************************************************
|
||||
** SCO over HCI Function Declarations
|
||||
*****************************************************************************/
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sco_co_init
|
||||
**
|
||||
** Description This function can be used by the phone to initialize audio
|
||||
** codec or for other initialization purposes before SCO connection
|
||||
** is opened.
|
||||
**
|
||||
**
|
||||
** Returns Void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern tBTA_DM_SCO_ROUTE_TYPE bta_dm_sco_co_init(UINT32 rx_bw, UINT32 tx_bw,
|
||||
tBTA_CODEC_INFO *p_codec_info, UINT8 app_id);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sco_co_open
|
||||
**
|
||||
** Description This function is executed when a SCO connection is open.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_sco_co_open(UINT16 handle, UINT8 pkt_size, UINT16 event);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sco_co_close
|
||||
**
|
||||
** Description This function is called when a SCO connection is closed
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_sco_co_close(void);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sco_co_out_data
|
||||
**
|
||||
** Description This function is called to send SCO data over HCI.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_sco_co_out_data(BT_HDR **p_buf);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sco_co_in_data
|
||||
**
|
||||
** Description This function is called to send incoming SCO data to application.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status);
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_co_ble_io_req
|
||||
**
|
||||
** Description This callout function is executed by DM to get BLE IO capabilities
|
||||
** before SMP pairing gets going.
|
||||
**
|
||||
** Parameters bd_addr - The peer device
|
||||
** *p_io_cap - The local Input/Output capabilities
|
||||
** *p_oob_data - TRUE, if OOB data is available for the peer device.
|
||||
** *p_auth_req - Auth request setting (Bonding and MITM required or not)
|
||||
** *p_max_key_size - max key size local device supported.
|
||||
** *p_init_key - initiator keys.
|
||||
** *p_resp_key - responder keys.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_co_ble_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap,
|
||||
tBTA_OOB_DATA *p_oob_data,
|
||||
tBTA_LE_AUTH_REQ *p_auth_req,
|
||||
UINT8 *p_max_key_size,
|
||||
tBTA_LE_KEY_TYPE *p_init_key,
|
||||
tBTA_LE_KEY_TYPE *p_resp_key );
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_co_ble_local_key_reload
|
||||
**
|
||||
** Description This callout function is to load the local BLE keys if available
|
||||
** on the device.
|
||||
**
|
||||
** Parameters none
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_co_ble_load_local_keys (tBTA_DM_BLE_LOCAL_KEY_MASK *p_key_mask, BT_OCTET16 er,
|
||||
tBTA_BLE_LOCAL_ID_KEYS *p_id_keys);
|
||||
|
||||
// btla-specific ++
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_co_ble_io_req
|
||||
**
|
||||
** Description This callout function is executed by DM to get BLE IO capabilities
|
||||
** before SMP pairing gets going.
|
||||
**
|
||||
** Parameters bd_addr - The peer device
|
||||
** *p_io_cap - The local Input/Output capabilities
|
||||
** *p_oob_data - TRUE, if OOB data is available for the peer device.
|
||||
** *p_auth_req - Auth request setting (Bonding and MITM required or not)
|
||||
** *p_max_key_size - max key size local device supported.
|
||||
** *p_init_key - initiator keys.
|
||||
** *p_resp_key - responder keys.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_co_ble_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap,
|
||||
tBTA_OOB_DATA *p_oob_data,
|
||||
tBTA_LE_AUTH_REQ *p_auth_req,
|
||||
UINT8 *p_max_key_size,
|
||||
tBTA_LE_KEY_TYPE *p_init_key,
|
||||
tBTA_LE_KEY_TYPE *p_resp_key );
|
||||
// btla-specific --
|
||||
|
||||
#endif
|
||||
1416
components/bt/bluedroid/bta/include/bta_gatt_api.h
Normal file
1416
components/bt/bluedroid/bta/include/bta_gatt_api.h
Normal file
File diff suppressed because it is too large
Load Diff
117
components/bt/bluedroid/bta/include/bta_gattc_ci.h
Normal file
117
components/bt/bluedroid/bta/include/bta_gattc_ci.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the interface file for GATT call-in functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_GATTC_CI_H
|
||||
#define BTA_GATTC_CI_H
|
||||
|
||||
#include "bta_gatt_api.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and data types
|
||||
*****************************************************************************/
|
||||
|
||||
/* Open Complete Event */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATT_STATUS status;
|
||||
} tBTA_GATTC_CI_EVT;
|
||||
|
||||
#define BTA_GATTC_NV_LOAD_MAX 10
|
||||
|
||||
/* Read Ready Event */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATT_STATUS status;
|
||||
UINT16 num_attr;
|
||||
tBTA_GATTC_NV_ATTR attr[BTA_GATTC_NV_LOAD_MAX];
|
||||
} tBTA_GATTC_CI_LOAD;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Function Declarations
|
||||
*****************************************************************************/
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_ci_cache_open
|
||||
**
|
||||
** Description This function sends an event to indicate server cache open
|
||||
** completed.
|
||||
**
|
||||
** Parameters server_bda - server BDA of this cache.
|
||||
** status - BTA_GATT_OK if full buffer of data,
|
||||
** BTA_GATT_FAIL if an error has occurred.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_gattc_ci_cache_open(BD_ADDR server_bda, UINT16 evt,
|
||||
tBTA_GATT_STATUS status, UINT16 conn_id);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_ci_cache_load
|
||||
**
|
||||
** Description This function sends an event to BTA indicating the phone has
|
||||
** load the servere cache and ready to send it to the stack.
|
||||
**
|
||||
** Parameters server_bda - server BDA of this cache.
|
||||
** num_bytes_read - number of bytes read into the buffer
|
||||
** specified in the read callout-function.
|
||||
** status - BTA_GATT_OK if full buffer of data,
|
||||
** BTA_GATT_FAIL if an error has occurred.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_gattc_ci_cache_load(BD_ADDR server_bda, UINT16 evt,
|
||||
UINT16 num_attr, tBTA_GATTC_NV_ATTR *p_atrr,
|
||||
tBTA_GATT_STATUS status, UINT16 conn_id);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_ci_save
|
||||
**
|
||||
** Description This function sends an event to BTA indicating the phone has
|
||||
** save the server cache.
|
||||
**
|
||||
** Parameters server_bda - server BDA of this cache.
|
||||
** status - BTA_GATT_OK if full buffer of data,
|
||||
** BTA_GATT_FAIL if an error has occurred.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_gattc_ci_cache_save(BD_ADDR server_bda, UINT16 evt,
|
||||
tBTA_GATT_STATUS status, UINT16 conn_id);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BTA_GATTC_CI_H */
|
||||
114
components/bt/bluedroid/bta/include/bta_gattc_co.h
Normal file
114
components/bt/bluedroid/bta/include/bta_gattc_co.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009-2013 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the interface file for BTA GATT client call-out functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_GATTC_CO_H
|
||||
#define BTA_GATTC_CO_H
|
||||
|
||||
#include "bta_gatt_api.h"
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_co_cache_open
|
||||
**
|
||||
** Description This callout function is executed by GATTC when a GATT server
|
||||
** cache is ready to be sent.
|
||||
**
|
||||
** Parameter server_bda: server bd address of this cache belongs to
|
||||
** evt: call in event to be passed in when cache open is done.
|
||||
** conn_id: connection ID of this cache operation attach to.
|
||||
** to_save: open cache to save or to load.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_gattc_co_cache_open(BD_ADDR server_bda, UINT16 evt,
|
||||
UINT16 conn_id, BOOLEAN to_save);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_co_cache_close
|
||||
**
|
||||
** Description This callout function is executed by GATTC when a GATT server
|
||||
** cache is written completely.
|
||||
**
|
||||
** Parameter server_bda: server bd address of this cache belongs to
|
||||
** conn_id: connection ID of this cache operation attach to.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_gattc_co_cache_close(BD_ADDR server_bda, UINT16 conn_id);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_co_cache_save
|
||||
**
|
||||
** Description This callout function is executed by GATT when a server cache
|
||||
** is available to save.
|
||||
**
|
||||
** Parameter server_bda: server bd address of this cache belongs to
|
||||
** evt: call in event to be passed in when cache save is done.
|
||||
** num_attr: number of attribute to be save.
|
||||
** p_attr: pointer to the list of attributes to save.
|
||||
** attr_index: starting attribute index of the save operation.
|
||||
** conn_id: connection ID of this cache operation attach to.
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_gattc_co_cache_save(BD_ADDR server_bda, UINT16 evt,
|
||||
UINT16 num_attr, tBTA_GATTC_NV_ATTR *p_attr,
|
||||
UINT16 attr_index, UINT16 conn_id);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_co_cache_load
|
||||
**
|
||||
** Description This callout function is executed by GATT when server cache
|
||||
** is required to load.
|
||||
**
|
||||
** Parameter server_bda: server bd address of this cache belongs to
|
||||
** evt: call in event to be passed in when cache save is done.
|
||||
** num_attr: number of attribute to be save.
|
||||
** attr_index: starting attribute index of the save operation.
|
||||
** conn_id: connection ID of this cache operation attach to.
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_gattc_co_cache_load(BD_ADDR server_bda, UINT16 evt,
|
||||
UINT16 start_index, UINT16 conn_id);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_co_cache_reset
|
||||
**
|
||||
** Description This callout function is executed by GATTC to reset cache in
|
||||
** application
|
||||
**
|
||||
** Parameter server_bda: server bd address of this cache belongs to
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_gattc_co_cache_reset(BD_ADDR server_bda);
|
||||
|
||||
#endif /* BTA_GATT_CO_H */
|
||||
525
components/bt/bluedroid/bta/include/bta_gattc_int.h
Normal file
525
components/bt/bluedroid/bta/include/bta_gattc_int.h
Normal file
@@ -0,0 +1,525 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the private file for the file transfer client (FTC).
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_GATTC_INT_H
|
||||
#define BTA_GATTC_INT_H
|
||||
|
||||
#include "bt_target.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_gatt_api.h"
|
||||
#include "bta_gattc_ci.h"
|
||||
#include "bta_gattc_co.h"
|
||||
|
||||
#include "gki.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and data types
|
||||
*****************************************************************************/
|
||||
enum {
|
||||
BTA_GATTC_API_OPEN_EVT = BTA_SYS_EVT_START(BTA_ID_GATTC),
|
||||
BTA_GATTC_INT_OPEN_FAIL_EVT,
|
||||
BTA_GATTC_API_CANCEL_OPEN_EVT,
|
||||
BTA_GATTC_INT_CANCEL_OPEN_OK_EVT,
|
||||
|
||||
BTA_GATTC_API_READ_EVT,
|
||||
BTA_GATTC_API_WRITE_EVT,
|
||||
BTA_GATTC_API_EXEC_EVT,
|
||||
BTA_GATTC_API_CFG_MTU_EVT,
|
||||
|
||||
BTA_GATTC_API_CLOSE_EVT,
|
||||
|
||||
BTA_GATTC_API_SEARCH_EVT,
|
||||
BTA_GATTC_API_CONFIRM_EVT,
|
||||
BTA_GATTC_API_READ_MULTI_EVT,
|
||||
BTA_GATTC_API_REFRESH_EVT,
|
||||
|
||||
BTA_GATTC_INT_CONN_EVT,
|
||||
BTA_GATTC_INT_DISCOVER_EVT,
|
||||
BTA_GATTC_DISCOVER_CMPL_EVT,
|
||||
BTA_GATTC_OP_CMPL_EVT,
|
||||
BTA_GATTC_INT_DISCONN_EVT,
|
||||
|
||||
/* for cache loading/saving */
|
||||
BTA_GATTC_START_CACHE_EVT,
|
||||
BTA_GATTC_CI_CACHE_OPEN_EVT,
|
||||
BTA_GATTC_CI_CACHE_LOAD_EVT,
|
||||
BTA_GATTC_CI_CACHE_SAVE_EVT,
|
||||
|
||||
BTA_GATTC_INT_START_IF_EVT,
|
||||
BTA_GATTC_API_REG_EVT,
|
||||
BTA_GATTC_API_DEREG_EVT,
|
||||
BTA_GATTC_API_LISTEN_EVT,
|
||||
BTA_GATTC_API_BROADCAST_EVT,
|
||||
BTA_GATTC_API_DISABLE_EVT,
|
||||
BTA_GATTC_ENC_CMPL_EVT
|
||||
};
|
||||
typedef UINT16 tBTA_GATTC_INT_EVT;
|
||||
|
||||
/* max client application GATTC can support */
|
||||
#ifndef BTA_GATTC_CL_MAX
|
||||
#define BTA_GATTC_CL_MAX 3 // 32
|
||||
#endif
|
||||
|
||||
/* max known devices GATTC can support */
|
||||
#ifndef BTA_GATTC_KNOWN_SR_MAX
|
||||
#define BTA_GATTC_KNOWN_SR_MAX 3 // 10
|
||||
#endif
|
||||
|
||||
#define BTA_GATTC_CONN_MAX GATT_MAX_PHY_CHANNEL
|
||||
|
||||
#ifndef BTA_GATTC_CLCB_MAX
|
||||
#define BTA_GATTC_CLCB_MAX GATT_CL_MAX_LCB
|
||||
#endif
|
||||
|
||||
#define BTA_GATTC_WRITE_PREPARE GATT_WRITE_PREPARE
|
||||
|
||||
|
||||
/* internal strucutre for GATTC register API */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBT_UUID app_uuid;
|
||||
tBTA_GATTC_CBACK *p_cback;
|
||||
} tBTA_GATTC_API_REG;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATTC_IF client_if;
|
||||
} tBTA_GATTC_INT_START_IF;
|
||||
|
||||
typedef tBTA_GATTC_INT_START_IF tBTA_GATTC_API_DEREG;
|
||||
typedef tBTA_GATTC_INT_START_IF tBTA_GATTC_INT_DEREG;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR remote_bda;
|
||||
tBTA_GATTC_IF client_if;
|
||||
BOOLEAN is_direct;
|
||||
tBTA_TRANSPORT transport;
|
||||
} tBTA_GATTC_API_OPEN;
|
||||
|
||||
typedef tBTA_GATTC_API_OPEN tBTA_GATTC_API_CANCEL_OPEN;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATT_AUTH_REQ auth_req;
|
||||
tBTA_GATT_SRVC_ID srvc_id;
|
||||
tBTA_GATT_ID char_id;
|
||||
tBTA_GATT_ID *p_descr_type;
|
||||
} tBTA_GATTC_API_READ;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATT_AUTH_REQ auth_req;
|
||||
tBTA_GATT_SRVC_ID srvc_id;
|
||||
tBTA_GATT_ID char_id;
|
||||
tBTA_GATT_ID *p_descr_type;
|
||||
tBTA_GATTC_WRITE_TYPE write_type;
|
||||
UINT16 offset;
|
||||
UINT16 len;
|
||||
UINT8 *p_value;
|
||||
} tBTA_GATTC_API_WRITE;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BOOLEAN is_execute;
|
||||
} tBTA_GATTC_API_EXEC;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATT_SRVC_ID srvc_id;
|
||||
tBTA_GATT_ID char_id;
|
||||
} tBTA_GATTC_API_CONFIRM;
|
||||
|
||||
typedef tGATT_CL_COMPLETE tBTA_GATTC_CMPL;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT8 op_code;
|
||||
tGATT_STATUS status;
|
||||
tBTA_GATTC_CMPL *p_cmpl;
|
||||
} tBTA_GATTC_OP_CMPL;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBT_UUID *p_srvc_uuid;
|
||||
} tBTA_GATTC_API_SEARCH;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATT_AUTH_REQ auth_req;
|
||||
UINT8 num_attr;
|
||||
tBTA_GATTC_ATTR_ID *p_id_list;
|
||||
} tBTA_GATTC_API_READ_MULTI;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR_PTR remote_bda;
|
||||
tBTA_GATTC_IF client_if;
|
||||
BOOLEAN start;
|
||||
} tBTA_GATTC_API_LISTEN;
|
||||
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT16 mtu;
|
||||
} tBTA_GATTC_API_CFG_MTU;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR remote_bda;
|
||||
tBTA_GATTC_IF client_if;
|
||||
UINT8 role;
|
||||
tBT_TRANSPORT transport;
|
||||
tGATT_DISCONN_REASON reason;
|
||||
} tBTA_GATTC_INT_CONN;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR remote_bda;
|
||||
tBTA_GATTC_IF client_if;
|
||||
} tBTA_GATTC_ENC_CMPL;
|
||||
|
||||
typedef union {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATTC_API_REG api_reg;
|
||||
tBTA_GATTC_API_DEREG api_dereg;
|
||||
tBTA_GATTC_API_OPEN api_conn;
|
||||
tBTA_GATTC_API_CANCEL_OPEN api_cancel_conn;
|
||||
tBTA_GATTC_API_READ api_read;
|
||||
tBTA_GATTC_API_SEARCH api_search;
|
||||
tBTA_GATTC_API_WRITE api_write;
|
||||
tBTA_GATTC_API_CONFIRM api_confirm;
|
||||
tBTA_GATTC_API_EXEC api_exec;
|
||||
tBTA_GATTC_API_READ_MULTI api_read_multi;
|
||||
tBTA_GATTC_API_CFG_MTU api_mtu;
|
||||
tBTA_GATTC_OP_CMPL op_cmpl;
|
||||
tBTA_GATTC_CI_EVT ci_open;
|
||||
tBTA_GATTC_CI_EVT ci_save;
|
||||
tBTA_GATTC_CI_LOAD ci_load;
|
||||
tBTA_GATTC_INT_CONN int_conn;
|
||||
tBTA_GATTC_ENC_CMPL enc_cmpl;
|
||||
|
||||
tBTA_GATTC_INT_START_IF int_start_if;
|
||||
tBTA_GATTC_INT_DEREG int_dereg;
|
||||
/* if peripheral role is supported */
|
||||
tBTA_GATTC_API_LISTEN api_listen;
|
||||
|
||||
} tBTA_GATTC_DATA;
|
||||
|
||||
|
||||
/* GATT server cache on the client */
|
||||
typedef union {
|
||||
UINT8 uuid128[LEN_UUID_128];
|
||||
UINT16 uuid16;
|
||||
} tBTA_GATTC_UUID;
|
||||
|
||||
typedef struct gattc_attr_cache {
|
||||
tBTA_GATTC_UUID *p_uuid;
|
||||
struct gattc_attr_cache *p_next;
|
||||
UINT16 uuid_len;
|
||||
UINT16 attr_handle;
|
||||
UINT8 inst_id;
|
||||
tBTA_GATT_CHAR_PROP property; /* if characteristic, it is char property;
|
||||
if included service, flag primary,
|
||||
if descriptor, not used */
|
||||
tBTA_GATTC_ATTR_TYPE attr_type;
|
||||
// btla-specific ++
|
||||
} __attribute__((packed)) tBTA_GATTC_CACHE_ATTR;
|
||||
// btla-specific --
|
||||
|
||||
typedef struct gattc_svc_cache {
|
||||
tBTA_GATT_SRVC_ID service_uuid;
|
||||
tBTA_GATTC_CACHE_ATTR *p_attr;
|
||||
tBTA_GATTC_CACHE_ATTR *p_last_attr;
|
||||
UINT16 s_handle;
|
||||
UINT16 e_handle;
|
||||
struct gattc_svc_cache *p_next;
|
||||
tBTA_GATTC_CACHE_ATTR *p_cur_char;
|
||||
// btla-specific ++
|
||||
} __attribute__((packed)) tBTA_GATTC_CACHE;
|
||||
// btla-specific --
|
||||
|
||||
typedef struct {
|
||||
tBT_UUID uuid;
|
||||
UINT16 s_handle;
|
||||
UINT16 e_handle;
|
||||
BOOLEAN is_primary;
|
||||
UINT8 srvc_inst_id;
|
||||
tBTA_GATT_CHAR_PROP property;
|
||||
} tBTA_GATTC_ATTR_REC;
|
||||
|
||||
|
||||
#define BTA_GATTC_MAX_CACHE_CHAR 40
|
||||
#define BTA_GATTC_ATTR_LIST_SIZE (BTA_GATTC_MAX_CACHE_CHAR * sizeof(tBTA_GATTC_ATTR_REC))
|
||||
|
||||
#ifndef BTA_GATTC_CACHE_SRVR_SIZE
|
||||
#define BTA_GATTC_CACHE_SRVR_SIZE 600
|
||||
#endif
|
||||
|
||||
enum {
|
||||
BTA_GATTC_IDLE_ST = 0, /* Idle */
|
||||
BTA_GATTC_W4_CONN_ST, /* Wait for connection - (optional) */
|
||||
BTA_GATTC_CONN_ST, /* connected state */
|
||||
BTA_GATTC_DISCOVER_ST /* discover is in progress */
|
||||
};
|
||||
typedef UINT8 tBTA_GATTC_STATE;
|
||||
|
||||
typedef struct {
|
||||
BOOLEAN in_use;
|
||||
BD_ADDR server_bda;
|
||||
BOOLEAN connected;
|
||||
|
||||
#define BTA_GATTC_SERV_IDLE 0
|
||||
#define BTA_GATTC_SERV_LOAD 1
|
||||
#define BTA_GATTC_SERV_SAVE 2
|
||||
#define BTA_GATTC_SERV_DISC 3
|
||||
#define BTA_GATTC_SERV_DISC_ACT 4
|
||||
|
||||
UINT8 state;
|
||||
|
||||
tBTA_GATTC_CACHE *p_srvc_cache;
|
||||
tBTA_GATTC_CACHE *p_cur_srvc;
|
||||
BUFFER_Q cache_buffer; /* buffer queue used for storing the cache data */
|
||||
UINT8 *p_free; /* starting point to next available byte */
|
||||
UINT16 free_byte; /* number of available bytes in server cache buffer */
|
||||
UINT8 update_count; /* indication received */
|
||||
UINT8 num_clcb; /* number of associated CLCB */
|
||||
|
||||
|
||||
tBTA_GATTC_ATTR_REC *p_srvc_list;
|
||||
UINT8 cur_srvc_idx;
|
||||
UINT8 cur_char_idx;
|
||||
UINT8 next_avail_idx;
|
||||
UINT8 total_srvc;
|
||||
UINT8 total_char;
|
||||
|
||||
UINT8 srvc_hdl_chg; /* service handle change indication pending */
|
||||
UINT16 attr_index; /* cahce NV saving/loading attribute index */
|
||||
|
||||
UINT16 mtu;
|
||||
} tBTA_GATTC_SERV;
|
||||
|
||||
#ifndef BTA_GATTC_NOTIF_REG_MAX
|
||||
#define BTA_GATTC_NOTIF_REG_MAX 15
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
BOOLEAN in_use;
|
||||
BD_ADDR remote_bda;
|
||||
tBTA_GATTC_CHAR_ID char_id;
|
||||
} tBTA_GATTC_NOTIF_REG;
|
||||
|
||||
typedef struct {
|
||||
tBTA_GATTC_CBACK *p_cback;
|
||||
BOOLEAN in_use;
|
||||
tBTA_GATTC_IF client_if; /* client interface with BTE stack for this application */
|
||||
UINT8 num_clcb; /* number of associated CLCB */
|
||||
BOOLEAN dereg_pending;
|
||||
tBT_UUID app_uuid;
|
||||
tBTA_GATTC_NOTIF_REG notif_reg[BTA_GATTC_NOTIF_REG_MAX];
|
||||
} tBTA_GATTC_RCB;
|
||||
|
||||
/* client channel is a mapping between a BTA client(cl_id) and a remote BD address */
|
||||
typedef struct {
|
||||
UINT16 bta_conn_id; /* client channel ID, unique for clcb */
|
||||
BD_ADDR bda;
|
||||
tBTA_TRANSPORT transport; /* channel transport */
|
||||
tBTA_GATTC_RCB *p_rcb; /* pointer to the registration CB */
|
||||
tBTA_GATTC_SERV *p_srcb; /* server cache CB */
|
||||
tBTA_GATTC_DATA *p_q_cmd; /* command in queue waiting for execution */
|
||||
|
||||
#define BTA_GATTC_NO_SCHEDULE 0
|
||||
#define BTA_GATTC_DISC_WAITING 0x01
|
||||
#define BTA_GATTC_REQ_WAITING 0x10
|
||||
|
||||
UINT8 auto_update; /* auto update is waiting */
|
||||
BOOLEAN disc_active;
|
||||
BOOLEAN in_use;
|
||||
tBTA_GATTC_STATE state;
|
||||
tBTA_GATT_STATUS status;
|
||||
UINT16 reason;
|
||||
} tBTA_GATTC_CLCB;
|
||||
|
||||
/* back ground connection tracking information */
|
||||
#if GATT_MAX_APPS <= 8
|
||||
typedef UINT8 tBTA_GATTC_CIF_MASK ;
|
||||
#elif GATT_MAX_APPS <= 16
|
||||
typedef UINT16 tBTA_GATTC_CIF_MASK;
|
||||
#elif GATT_MAX_APPS <= 32
|
||||
typedef UINT32 tBTA_GATTC_CIF_MASK;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
BOOLEAN in_use;
|
||||
BD_ADDR remote_bda;
|
||||
tBTA_GATTC_CIF_MASK cif_mask;
|
||||
tBTA_GATTC_CIF_MASK cif_adv_mask;
|
||||
|
||||
} tBTA_GATTC_BG_TCK;
|
||||
|
||||
typedef struct {
|
||||
BOOLEAN in_use;
|
||||
BD_ADDR remote_bda;
|
||||
} tBTA_GATTC_CONN;
|
||||
|
||||
enum {
|
||||
BTA_GATTC_STATE_DISABLED,
|
||||
BTA_GATTC_STATE_ENABLING,
|
||||
BTA_GATTC_STATE_ENABLED,
|
||||
BTA_GATTC_STATE_DISABLING
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
UINT8 state;
|
||||
|
||||
tBTA_GATTC_CONN conn_track[BTA_GATTC_CONN_MAX];
|
||||
tBTA_GATTC_BG_TCK bg_track[BTA_GATTC_KNOWN_SR_MAX];
|
||||
tBTA_GATTC_RCB cl_rcb[BTA_GATTC_CL_MAX];
|
||||
|
||||
tBTA_GATTC_CLCB clcb[BTA_GATTC_CLCB_MAX];
|
||||
tBTA_GATTC_SERV known_server[BTA_GATTC_KNOWN_SR_MAX];
|
||||
|
||||
tSDP_DISCOVERY_DB *p_sdp_db;
|
||||
UINT16 sdp_conn_id;
|
||||
} tBTA_GATTC_CB;
|
||||
|
||||
/*****************************************************************************
|
||||
** Global data
|
||||
*****************************************************************************/
|
||||
|
||||
/* GATTC control block */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
extern tBTA_GATTC_CB bta_gattc_cb;
|
||||
#else
|
||||
extern tBTA_GATTC_CB *bta_gattc_cb_ptr;
|
||||
#define bta_gattc_cb (*bta_gattc_cb_ptr)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
** Function prototypes
|
||||
*****************************************************************************/
|
||||
extern BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg);
|
||||
extern BOOLEAN bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data);
|
||||
|
||||
/* function processed outside SM */
|
||||
extern void bta_gattc_disable(tBTA_GATTC_CB *p_cb);
|
||||
extern void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_start_if(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
|
||||
extern void bta_gattc_process_api_open_cancel (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
|
||||
extern void bta_gattc_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_RCB *p_clreg);
|
||||
extern void bta_gattc_process_enc_cmpl(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
|
||||
|
||||
/* function within state machine */
|
||||
extern void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_open_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
|
||||
extern void bta_gattc_cancel_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_cancel_open_ok(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_cancel_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
|
||||
extern void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
|
||||
extern void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_close_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_disc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
|
||||
extern void bta_gattc_start_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_read(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_write(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_q_cmd(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_search(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_execute(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_ci_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_ci_load(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_ci_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_ci_save(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_cache_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_ignore_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_restart_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_msg);
|
||||
extern void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg);
|
||||
extern void bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN *p_data);
|
||||
extern void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status,
|
||||
BD_ADDR remote_bda, UINT16 conn_id, tBTA_TRANSPORT transport, UINT16 mtu);
|
||||
extern void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
|
||||
extern void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
#if BLE_INCLUDED == TRUE
|
||||
extern void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
|
||||
extern void bta_gattc_broadcast(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
|
||||
#endif
|
||||
/* utility functions */
|
||||
extern tBTA_GATTC_CLCB *bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda, tBTA_TRANSPORT transport);
|
||||
extern tBTA_GATTC_CLCB *bta_gattc_find_clcb_by_conn_id (UINT16 conn_id);
|
||||
extern tBTA_GATTC_CLCB *bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_TRANSPORT transport);
|
||||
extern void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb);
|
||||
extern tBTA_GATTC_CLCB *bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_TRANSPORT transport);
|
||||
extern tBTA_GATTC_RCB *bta_gattc_cl_get_regcb(UINT8 client_if);
|
||||
extern tBTA_GATTC_SERV *bta_gattc_find_srcb(BD_ADDR bda);
|
||||
extern tBTA_GATTC_SERV *bta_gattc_srcb_alloc(BD_ADDR bda);
|
||||
extern tBTA_GATTC_SERV *bta_gattc_find_scb_by_cid (UINT16 conn_id);
|
||||
extern tBTA_GATTC_CLCB *bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA *p_msg);
|
||||
extern tBTA_GATTC_CLCB *bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA *p_msg);
|
||||
|
||||
extern BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
|
||||
extern UINT16 bta_gattc_id2handle(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_SRVC_ID *p_service_id, tBTA_GATT_ID *p_char_id, tBTA_GATT_ID *p_descr_uuid);
|
||||
extern BOOLEAN bta_gattc_handle2id(tBTA_GATTC_SERV *p_srcb, UINT16 handle, tBTA_GATT_SRVC_ID *service_id, tBTA_GATT_ID *char_id, tBTA_GATT_ID *p_type);
|
||||
extern BOOLEAN bta_gattc_uuid_compare (tBT_UUID *p_src, tBT_UUID *p_tar, BOOLEAN is_precise);
|
||||
extern void bta_gattc_pack_attr_uuid(tBTA_GATTC_CACHE_ATTR *p_attr, tBT_UUID *p_uuid);
|
||||
extern BOOLEAN bta_gattc_check_notif_registry(tBTA_GATTC_RCB *p_clreg, tBTA_GATTC_SERV *p_srcb, tBTA_GATTC_NOTIFY *p_notify);
|
||||
extern tBTA_GATT_STATUS bta_gattc_pack_read_cb_data(tBTA_GATTC_SERV *p_srcb, tBT_UUID *p_descr_uuid, tGATT_VALUE *p_attr, tBTA_GATT_READ_VAL *p_value);
|
||||
extern BOOLEAN bta_gattc_mark_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR_PTR remote_bda, BOOLEAN add, BOOLEAN is_listen);
|
||||
extern BOOLEAN bta_gattc_check_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR remote_bda, UINT8 role);
|
||||
extern UINT8 bta_gattc_num_reg_app(void);
|
||||
extern void bta_gattc_clear_notif_registration(UINT16 conn_id);
|
||||
extern tBTA_GATTC_SERV *bta_gattc_find_srvr_cache(BD_ADDR bda);
|
||||
extern BOOLEAN bta_gattc_charid_compare(tBTA_GATTC_CHAR_ID *p_src, tBTA_GATTC_CHAR_ID *p_tar);
|
||||
extern BOOLEAN bta_gattc_srvcid_compare(tBTA_GATT_SRVC_ID *p_src, tBTA_GATT_SRVC_ID *p_tar);
|
||||
extern void bta_gattc_cpygattid(tBTA_GATT_ID *p_des, tBTA_GATT_ID *p_src);
|
||||
|
||||
/* discovery functions */
|
||||
extern void bta_gattc_disc_res_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_DISC_RES *p_data);
|
||||
extern void bta_gattc_disc_cmpl_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_STATUS status);
|
||||
extern tBTA_GATT_STATUS bta_gattc_discover_procedure(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb, UINT8 disc_type);
|
||||
extern tBTA_GATT_STATUS bta_gattc_discover_pri_service(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb, UINT8 disc_type);
|
||||
extern void bta_gattc_search_service(tBTA_GATTC_CLCB *p_clcb, tBT_UUID *p_uuid);
|
||||
extern tBTA_GATT_STATUS bta_gattc_query_cache(UINT16 conn_id, UINT8 query_type, tBTA_GATT_SRVC_ID *p_srvc_id,
|
||||
tBTA_GATT_ID *p_start_rec, tBT_UUID *p_uuid_cond,
|
||||
tBTA_GATT_ID *p_output, void *p_param);
|
||||
extern tBTA_GATT_STATUS bta_gattc_init_cache(tBTA_GATTC_SERV *p_srvc_cb);
|
||||
extern void bta_gattc_rebuild_cache(tBTA_GATTC_SERV *p_srcv, UINT16 num_attr, tBTA_GATTC_NV_ATTR *p_attr, UINT16 attr_index);
|
||||
extern BOOLEAN bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id);
|
||||
|
||||
|
||||
extern tBTA_GATTC_CONN *bta_gattc_conn_alloc(BD_ADDR remote_bda);
|
||||
extern tBTA_GATTC_CONN *bta_gattc_conn_find(BD_ADDR remote_bda);
|
||||
extern tBTA_GATTC_CONN *bta_gattc_conn_find_alloc(BD_ADDR remote_bda);
|
||||
extern BOOLEAN bta_gattc_conn_dealloc(BD_ADDR remote_bda);
|
||||
|
||||
#endif /* BTA_GATTC_INT_H */
|
||||
81
components/bt/bluedroid/bta/include/bta_gatts_co.h
Normal file
81
components/bt/bluedroid/bta/include/bta_gatts_co.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the interface file for BTA GATT server call-out functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_GATTS_CO_H
|
||||
#define BTA_GATTS_CO_H
|
||||
|
||||
#include "bta_gatt_api.h"
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_co_update_handle_range
|
||||
**
|
||||
** Description This callout function is executed by GATTS when a GATT server
|
||||
** handle range ios to be added or removed.
|
||||
**
|
||||
** Parameter is_add: true is to add a handle range; otherwise is to delete.
|
||||
** p_hndl_range: handle range.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_gatts_co_update_handle_range(BOOLEAN is_add, tBTA_GATTS_HNDL_RANGE *p_hndl_range);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_co_srv_chg
|
||||
**
|
||||
** Description This call-out is to read/write/remove service change related
|
||||
** informaiton. The request consists of the cmd and p_req and the
|
||||
** response is returned in p_rsp
|
||||
**
|
||||
** Parameter cmd - request command
|
||||
** p_req - request paramters
|
||||
** p_rsp - response data for the request
|
||||
**
|
||||
** Returns TRUE - if the request is processed successfully and
|
||||
** the response is returned in p_rsp.
|
||||
** FASLE - if the request can not be processed
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern BOOLEAN bta_gatts_co_srv_chg(tBTA_GATTS_SRV_CHG_CMD cmd,
|
||||
tBTA_GATTS_SRV_CHG_REQ *p_req,
|
||||
tBTA_GATTS_SRV_CHG_RSP *p_rsp);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_co_load_handle_range
|
||||
**
|
||||
** Description This callout function is executed by GATTS when a GATT server
|
||||
** handle range is requested to be loaded from NV.
|
||||
**
|
||||
** Parameter
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern BOOLEAN bta_gatts_co_load_handle_range(UINT8 index,
|
||||
tBTA_GATTS_HNDL_RANGE *p_handle);
|
||||
|
||||
|
||||
#endif /* BTA_GATTS_CO_H */
|
||||
256
components/bt/bluedroid/bta/include/bta_gatts_int.h
Normal file
256
components/bt/bluedroid/bta/include/bta_gatts_int.h
Normal file
@@ -0,0 +1,256 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the private file for the BTA GATT server.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_GATTS_INT_H
|
||||
#define BTA_GATTS_INT_H
|
||||
|
||||
#include "bt_target.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_gatt_api.h"
|
||||
#include "gatt_api.h"
|
||||
|
||||
#include "gki.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and data types
|
||||
*****************************************************************************/
|
||||
enum {
|
||||
BTA_GATTS_API_REG_EVT = BTA_SYS_EVT_START(BTA_ID_GATTS),
|
||||
BTA_GATTS_INT_START_IF_EVT,
|
||||
BTA_GATTS_API_DEREG_EVT,
|
||||
BTA_GATTS_API_CREATE_SRVC_EVT,
|
||||
BTA_GATTS_API_INDICATION_EVT,
|
||||
|
||||
BTA_GATTS_API_ADD_INCL_SRVC_EVT,
|
||||
BTA_GATTS_API_ADD_CHAR_EVT,
|
||||
BTA_GATTS_API_ADD_DESCR_EVT,
|
||||
BTA_GATTS_API_DEL_SRVC_EVT,
|
||||
BTA_GATTS_API_START_SRVC_EVT,
|
||||
BTA_GATTS_API_STOP_SRVC_EVT,
|
||||
BTA_GATTS_API_RSP_EVT,
|
||||
BTA_GATTS_API_SET_ATTR_VAL_EVT,
|
||||
BTA_GATTS_API_OPEN_EVT,
|
||||
BTA_GATTS_API_CANCEL_OPEN_EVT,
|
||||
BTA_GATTS_API_CLOSE_EVT,
|
||||
BTA_GATTS_API_LISTEN_EVT,
|
||||
BTA_GATTS_API_DISABLE_EVT
|
||||
};
|
||||
typedef UINT16 tBTA_GATTS_INT_EVT;
|
||||
|
||||
/* max number of application allowed on device */
|
||||
#define BTA_GATTS_MAX_APP_NUM GATT_MAX_SR_PROFILES
|
||||
|
||||
/* max number of services allowed in the device */
|
||||
#define BTA_GATTS_MAX_SRVC_NUM GATT_MAX_SR_PROFILES
|
||||
|
||||
/* internal strucutre for GATTC register API */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBT_UUID app_uuid;
|
||||
tBTA_GATTS_CBACK *p_cback;
|
||||
} tBTA_GATTS_API_REG;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATTS_IF server_if;
|
||||
} tBTA_GATTS_INT_START_IF;
|
||||
|
||||
typedef tBTA_GATTS_INT_START_IF tBTA_GATTS_API_DEREG;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATTS_IF server_if;
|
||||
tBT_UUID service_uuid;
|
||||
UINT16 num_handle;
|
||||
UINT8 inst;
|
||||
BOOLEAN is_pri;
|
||||
|
||||
} tBTA_GATTS_API_CREATE_SRVC;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBT_UUID char_uuid;
|
||||
tBTA_GATT_PERM perm;
|
||||
tBTA_GATT_CHAR_PROP property;
|
||||
tBTA_GATTS_ATTR_CONTROL control;
|
||||
tBTA_GATT_ATTR_VAL attr_val;
|
||||
} tBTA_GATTS_API_ADD_CHAR;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT16 included_service_id;
|
||||
} tBTA_GATTS_API_ADD_INCL_SRVC;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBT_UUID descr_uuid;
|
||||
tBTA_GATT_PERM perm;
|
||||
tBTA_GATTS_ATTR_CONTROL control;
|
||||
tBTA_GATT_ATTR_VAL attr_val;
|
||||
} tBTA_GATTS_API_ADD_DESCR;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT16 attr_id;
|
||||
UINT16 len;
|
||||
BOOLEAN need_confirm;
|
||||
UINT8 value[BTA_GATT_MAX_ATTR_LEN];
|
||||
} tBTA_GATTS_API_INDICATION;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT32 trans_id;
|
||||
tBTA_GATT_STATUS status;
|
||||
tBTA_GATTS_RSP *p_rsp;
|
||||
} tBTA_GATTS_API_RSP;
|
||||
|
||||
typedef struct{
|
||||
BT_HDR hdr;
|
||||
UINT16 length;
|
||||
UINT8 *value;
|
||||
}tBTA_GATTS_API_SET_ATTR_VAL;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATT_TRANSPORT transport;
|
||||
} tBTA_GATTS_API_START;
|
||||
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR remote_bda;
|
||||
tBTA_GATTS_IF server_if;
|
||||
BOOLEAN is_direct;
|
||||
tBTA_GATT_TRANSPORT transport;
|
||||
|
||||
} tBTA_GATTS_API_OPEN;
|
||||
|
||||
typedef tBTA_GATTS_API_OPEN tBTA_GATTS_API_CANCEL_OPEN;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR_PTR remote_bda;
|
||||
tBTA_GATTS_IF server_if;
|
||||
BOOLEAN start;
|
||||
} tBTA_GATTS_API_LISTEN;
|
||||
|
||||
typedef union {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATTS_API_REG api_reg;
|
||||
tBTA_GATTS_API_DEREG api_dereg;
|
||||
tBTA_GATTS_API_CREATE_SRVC api_create_svc;
|
||||
tBTA_GATTS_API_ADD_INCL_SRVC api_add_incl_srvc;
|
||||
tBTA_GATTS_API_ADD_CHAR api_add_char;
|
||||
tBTA_GATTS_API_ADD_DESCR api_add_char_descr;
|
||||
tBTA_GATTS_API_START api_start;
|
||||
tBTA_GATTS_API_INDICATION api_indicate;
|
||||
tBTA_GATTS_API_RSP api_rsp;
|
||||
tBTA_GATTS_API_SET_ATTR_VAL api_set_val;
|
||||
tBTA_GATTS_API_OPEN api_open;
|
||||
tBTA_GATTS_API_CANCEL_OPEN api_cancel_open;
|
||||
|
||||
tBTA_GATTS_INT_START_IF int_start_if;
|
||||
/* if peripheral role is supported */
|
||||
tBTA_GATTS_API_LISTEN api_listen;
|
||||
} tBTA_GATTS_DATA;
|
||||
|
||||
/* application registration control block */
|
||||
typedef struct {
|
||||
BOOLEAN in_use;
|
||||
tBT_UUID app_uuid;
|
||||
tBTA_GATTS_CBACK *p_cback;
|
||||
tBTA_GATTS_IF gatt_if;
|
||||
} tBTA_GATTS_RCB;
|
||||
|
||||
/* service registration control block */
|
||||
typedef struct {
|
||||
tBT_UUID service_uuid; /* service UUID */
|
||||
UINT16 service_id; /* service handle */
|
||||
UINT8 inst_num; /* instance ID */
|
||||
UINT8 rcb_idx;
|
||||
UINT8 idx; /* self index of serviec CB */
|
||||
BOOLEAN in_use;
|
||||
|
||||
} tBTA_GATTS_SRVC_CB;
|
||||
|
||||
|
||||
/* GATT server control block */
|
||||
typedef struct {
|
||||
BOOLEAN enabled;
|
||||
tBTA_GATTS_RCB rcb[BTA_GATTS_MAX_APP_NUM];
|
||||
tBTA_GATTS_SRVC_CB srvc_cb[BTA_GATTS_MAX_SRVC_NUM];
|
||||
} tBTA_GATTS_CB;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Global data
|
||||
*****************************************************************************/
|
||||
|
||||
/* GATTC control block */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
extern tBTA_GATTS_CB bta_gatts_cb;
|
||||
#else
|
||||
extern tBTA_GATTS_CB *bta_gatts_cb_ptr;
|
||||
#define bta_gatts_cb (*bta_gatts_cb_ptr)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
** Function prototypes
|
||||
*****************************************************************************/
|
||||
extern BOOLEAN bta_gatts_hdl_event(BT_HDR *p_msg);
|
||||
|
||||
extern void bta_gatts_api_disable(tBTA_GATTS_CB *p_cb);
|
||||
extern void bta_gatts_api_enable(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_data);
|
||||
extern void bta_gatts_register(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_start_if(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_deregister(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_create_srvc(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_add_include_srvc(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_set_attr_value(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_get_attr_value(UINT16 attr_handle, UINT16 *length, UINT8 **value);
|
||||
extern void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_start_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
|
||||
|
||||
extern void bta_gatts_send_rsp(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
|
||||
|
||||
extern void bta_gatts_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_cancel_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
|
||||
extern BOOLEAN bta_gatts_uuid_compare(tBT_UUID tar, tBT_UUID src);
|
||||
extern tBTA_GATTS_RCB *bta_gatts_find_app_rcb_by_app_if(tBTA_GATTS_IF server_if);
|
||||
extern UINT8 bta_gatts_find_app_rcb_idx_by_app_if(tBTA_GATTS_CB *p_cb, tBTA_GATTS_IF server_if);
|
||||
extern UINT8 bta_gatts_alloc_srvc_cb(tBTA_GATTS_CB *p_cb, UINT8 rcb_idx);
|
||||
extern tBTA_GATTS_SRVC_CB *bta_gatts_find_srvc_cb_by_srvc_id(tBTA_GATTS_CB *p_cb, UINT16 service_id);
|
||||
extern tBTA_GATTS_SRVC_CB *bta_gatts_find_srvc_cb_by_attr_id(tBTA_GATTS_CB *p_cb, UINT16 attr_id);
|
||||
|
||||
|
||||
#endif /* BTA_GATTS_INT_H */
|
||||
|
||||
541
components/bt/bluedroid/bta/include/bta_hh_api.h
Normal file
541
components/bt/bluedroid/bta/include/bta_hh_api.h
Normal file
@@ -0,0 +1,541 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002-2012 Broadcom Corporation
|
||||
*
|
||||
* 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 BTA_HH_API_H
|
||||
#define BTA_HH_API_H
|
||||
|
||||
#include "bta_api.h"
|
||||
#include "hidh_api.h"
|
||||
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
#include "gatt_api.h"
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and Type Definitions
|
||||
*****************************************************************************/
|
||||
#ifndef BTA_HH_DEBUG
|
||||
#define BTA_HH_DEBUG TRUE
|
||||
#endif
|
||||
|
||||
#ifndef BTA_HH_SSR_MAX_LATENCY_DEF
|
||||
#define BTA_HH_SSR_MAX_LATENCY_DEF 800 /* 500 ms*/
|
||||
#endif
|
||||
|
||||
#ifndef BTA_HH_SSR_MIN_TOUT_DEF
|
||||
#define BTA_HH_SSR_MIN_TOUT_DEF 2
|
||||
#endif
|
||||
|
||||
/* BTA HID Host callback events */
|
||||
#define BTA_HH_ENABLE_EVT 0 /* HH enabled */
|
||||
#define BTA_HH_DISABLE_EVT 1 /* HH disabled */
|
||||
#define BTA_HH_OPEN_EVT 2 /* connection opened */
|
||||
#define BTA_HH_CLOSE_EVT 3 /* connection closed */
|
||||
#define BTA_HH_GET_RPT_EVT 4 /* BTA_HhGetReport callback */
|
||||
#define BTA_HH_SET_RPT_EVT 5 /* BTA_HhSetReport callback */
|
||||
#define BTA_HH_GET_PROTO_EVT 6 /* BTA_GetProtoMode callback */
|
||||
#define BTA_HH_SET_PROTO_EVT 7 /* BTA_HhSetProtoMode callback */
|
||||
#define BTA_HH_GET_IDLE_EVT 8 /* BTA_HhGetIdle comes callback */
|
||||
#define BTA_HH_SET_IDLE_EVT 9 /* BTA_HhSetIdle finish callback */
|
||||
#define BTA_HH_GET_DSCP_EVT 10 /* Get report descriptor */
|
||||
#define BTA_HH_ADD_DEV_EVT 11 /* Add Device callback */
|
||||
#define BTA_HH_RMV_DEV_EVT 12 /* remove device finished */
|
||||
#define BTA_HH_VC_UNPLUG_EVT 13 /* virtually unplugged */
|
||||
#define BTA_HH_DATA_EVT 15
|
||||
#define BTA_HH_API_ERR_EVT 16 /* API error is caught */
|
||||
#define BTA_HH_UPDATE_SCPP_EVT 17 /* update scan paramter complete */
|
||||
|
||||
typedef UINT16 tBTA_HH_EVT;
|
||||
|
||||
/* application ID(none-zero) for each type of device */
|
||||
#define BTA_HH_APP_ID_MI 1
|
||||
#define BTA_HH_APP_ID_KB 2
|
||||
#define BTA_HH_APP_ID_RMC 3
|
||||
#define BTA_HH_APP_ID_3DSG 4
|
||||
#define BTA_HH_APP_ID_JOY 5
|
||||
#define BTA_HH_APP_ID_GPAD 6
|
||||
#define BTA_HH_APP_ID_LE 0xff
|
||||
|
||||
/* defined the minimum offset */
|
||||
#define BTA_HH_MIN_OFFSET L2CAP_MIN_OFFSET+1
|
||||
|
||||
/* HID_HOST_MAX_DEVICES can not exceed 15 for th design of BTA HH */
|
||||
#define BTA_HH_IDX_INVALID 0xff
|
||||
#define BTA_HH_MAX_KNOWN HID_HOST_MAX_DEVICES
|
||||
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
/* GATT_MAX_PHY_CHANNEL can not exceed 14 for the design of BTA HH */
|
||||
#define BTA_HH_LE_MAX_KNOWN GATT_MAX_PHY_CHANNEL
|
||||
#define BTA_HH_MAX_DEVICE (HID_HOST_MAX_DEVICES + GATT_MAX_PHY_CHANNEL)
|
||||
#else
|
||||
#define BTA_HH_MAX_DEVICE HID_HOST_MAX_DEVICES
|
||||
#endif
|
||||
/* invalid device handle */
|
||||
#define BTA_HH_INVALID_HANDLE 0xff
|
||||
|
||||
/* type of protocol mode */
|
||||
#define BTA_HH_PROTO_RPT_MODE (0x00)
|
||||
#define BTA_HH_PROTO_BOOT_MODE (0x01)
|
||||
#define BTA_HH_PROTO_UNKNOWN (0xff)
|
||||
typedef UINT8 tBTA_HH_PROTO_MODE;
|
||||
|
||||
enum {
|
||||
BTA_HH_KEYBD_RPT_ID = 1,
|
||||
BTA_HH_MOUSE_RPT_ID
|
||||
};
|
||||
typedef UINT8 tBTA_HH_BOOT_RPT_ID;
|
||||
|
||||
/* type of devices, bit mask */
|
||||
#define BTA_HH_DEVT_UNKNOWN 0x00
|
||||
#define BTA_HH_DEVT_JOS 0x01 /* joy stick */
|
||||
#define BTA_HH_DEVT_GPD 0x02 /* game pad */
|
||||
#define BTA_HH_DEVT_RMC 0x03 /* remote control */
|
||||
#define BTA_HH_DEVT_SED 0x04 /* sensing device */
|
||||
#define BTA_HH_DEVT_DGT 0x05 /* Digitizer tablet */
|
||||
#define BTA_HH_DEVT_CDR 0x06 /* card reader */
|
||||
#define BTA_HH_DEVT_KBD 0x10 /* keyboard */
|
||||
#define BTA_HH_DEVT_MIC 0x20 /* pointing device */
|
||||
#define BTA_HH_DEVT_COM 0x30 /* Combo keyboard/pointing */
|
||||
#define BTA_HH_DEVT_OTHER 0x80
|
||||
typedef UINT8 tBTA_HH_DEVT;
|
||||
|
||||
enum {
|
||||
BTA_HH_OK,
|
||||
BTA_HH_HS_HID_NOT_READY, /* handshake error : device not ready */
|
||||
BTA_HH_HS_INVALID_RPT_ID, /* handshake error : invalid report ID */
|
||||
BTA_HH_HS_TRANS_NOT_SPT, /* handshake error : transaction not spt */
|
||||
BTA_HH_HS_INVALID_PARAM, /* handshake error : invalid paremter */
|
||||
BTA_HH_HS_ERROR, /* handshake error : unspecified HS error */
|
||||
BTA_HH_ERR, /* general BTA HH error */
|
||||
BTA_HH_ERR_SDP, /* SDP error */
|
||||
BTA_HH_ERR_PROTO, /* SET_Protocol error,
|
||||
only used in BTA_HH_OPEN_EVT callback */
|
||||
|
||||
BTA_HH_ERR_DB_FULL, /* device database full error, used in
|
||||
BTA_HH_OPEN_EVT/BTA_HH_ADD_DEV_EVT */
|
||||
BTA_HH_ERR_TOD_UNSPT, /* type of device not supported */
|
||||
BTA_HH_ERR_NO_RES, /* out of system resources */
|
||||
BTA_HH_ERR_AUTH_FAILED, /* authentication fail */
|
||||
BTA_HH_ERR_HDL,
|
||||
BTA_HH_ERR_SEC
|
||||
};
|
||||
typedef UINT8 tBTA_HH_STATUS;
|
||||
|
||||
|
||||
#define BTA_HH_VIRTUAL_CABLE HID_VIRTUAL_CABLE
|
||||
#define BTA_HH_NORMALLY_CONNECTABLE HID_NORMALLY_CONNECTABLE
|
||||
#define BTA_HH_RECONN_INIT HID_RECONN_INIT
|
||||
#define BTA_HH_SDP_DISABLE HID_SDP_DISABLE
|
||||
#define BTA_HH_BATTERY_POWER HID_BATTERY_POWER
|
||||
#define BTA_HH_REMOTE_WAKE HID_REMOTE_WAKE
|
||||
#define BTA_HH_SUP_TOUT_AVLBL HID_SUP_TOUT_AVLBL
|
||||
#define BTA_HH_SEC_REQUIRED HID_SEC_REQUIRED
|
||||
typedef UINT16 tBTA_HH_ATTR_MASK;
|
||||
|
||||
/* supported type of device and corresponding application ID */
|
||||
typedef struct {
|
||||
tBTA_HH_DEVT tod; /* type of device */
|
||||
UINT8 app_id; /* corresponding application ID */
|
||||
} tBTA_HH_SPT_TOD;
|
||||
|
||||
/* configuration struct */
|
||||
typedef struct {
|
||||
UINT8 max_devt_spt; /* max number of types of devices spt */
|
||||
tBTA_HH_SPT_TOD *p_devt_list; /* supported types of device list */
|
||||
UINT16 sdp_db_size;
|
||||
} tBTA_HH_CFG;
|
||||
|
||||
enum {
|
||||
BTA_HH_RPTT_RESRV, /* reserved */
|
||||
BTA_HH_RPTT_INPUT, /* input report */
|
||||
BTA_HH_RPTT_OUTPUT, /* output report */
|
||||
BTA_HH_RPTT_FEATURE /* feature report */
|
||||
};
|
||||
typedef UINT8 tBTA_HH_RPT_TYPE;
|
||||
|
||||
/* HID_CONTROL operation code used in BTA_HhSendCtrl()
|
||||
*/
|
||||
enum {
|
||||
BTA_HH_CTRL_NOP = 0 + HID_PAR_CONTROL_NOP ,/* mapping from BTE */
|
||||
BTA_HH_CTRL_HARD_RESET, /* hard reset */
|
||||
BTA_HH_CTRL_SOFT_RESET, /* soft reset */
|
||||
BTA_HH_CTRL_SUSPEND, /* enter suspend */
|
||||
BTA_HH_CTRL_EXIT_SUSPEND, /* exit suspend */
|
||||
BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG /* virtual unplug */
|
||||
};
|
||||
typedef UINT8 tBTA_HH_TRANS_CTRL_TYPE;
|
||||
|
||||
typedef tHID_DEV_DSCP_INFO tBTA_HH_DEV_DESCR;
|
||||
|
||||
#define BTA_HH_SSR_PARAM_INVALID HID_SSR_PARAM_INVALID
|
||||
|
||||
/* id DI is not existing in remote device, vendor_id in tBTA_HH_DEV_DSCP_INFO will be set to 0xffff */
|
||||
#define BTA_HH_VENDOR_ID_INVALID 0xffff
|
||||
|
||||
|
||||
/* report descriptor information */
|
||||
typedef struct {
|
||||
UINT16 vendor_id; /* vendor ID */
|
||||
UINT16 product_id; /* product ID */
|
||||
UINT16 version; /* version */
|
||||
UINT16 ssr_max_latency; /* SSR max latency, BTA_HH_SSR_PARAM_INVALID if unknown */
|
||||
UINT16 ssr_min_tout; /* SSR min timeout, BTA_HH_SSR_PARAM_INVALID if unknown */
|
||||
UINT8 ctry_code; /*Country Code.*/
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
#define BTA_HH_LE_REMOTE_WAKE 0x01
|
||||
#define BTA_HH_LE_NORMAL_CONN 0x02
|
||||
|
||||
UINT8 flag;
|
||||
#endif
|
||||
tBTA_HH_DEV_DESCR descriptor;
|
||||
} tBTA_HH_DEV_DSCP_INFO;
|
||||
|
||||
/* callback event data for BTA_HH_OPEN_EVT */
|
||||
typedef struct {
|
||||
BD_ADDR bda; /* HID device bd address */
|
||||
tBTA_HH_STATUS status; /* operation status */
|
||||
UINT8 handle; /* device handle */
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
BOOLEAN le_hid; /* is LE devices? */
|
||||
BOOLEAN scps_supported; /* scan parameter service supported */
|
||||
#endif
|
||||
|
||||
} tBTA_HH_CONN;
|
||||
|
||||
typedef tBTA_HH_CONN tBTA_HH_DEV_INFO;
|
||||
|
||||
/* callback event data */
|
||||
typedef struct {
|
||||
tBTA_HH_STATUS status; /* operation status */
|
||||
UINT8 handle; /* device handle */
|
||||
} tBTA_HH_CBDATA;
|
||||
|
||||
enum {
|
||||
BTA_HH_MOD_CTRL_KEY,
|
||||
BTA_HH_MOD_SHFT_KEY,
|
||||
BTA_HH_MOD_ALT_KEY,
|
||||
BTA_HH_MOD_GUI_KEY,
|
||||
BTA_HH_MOD_MAX_KEY
|
||||
};
|
||||
|
||||
/* parsed boot mode keyboard report */
|
||||
typedef struct {
|
||||
UINT8 this_char[6]; /* virtual key code */
|
||||
BOOLEAN mod_key[BTA_HH_MOD_MAX_KEY];
|
||||
/* ctrl, shift, Alt, GUI */
|
||||
/* modifier key: is Shift key pressed */
|
||||
/* modifier key: is Ctrl key pressed */
|
||||
/* modifier key: is Alt key pressed */
|
||||
/* modifier key: GUI up/down */
|
||||
BOOLEAN caps_lock; /* is caps locked */
|
||||
BOOLEAN num_lock; /* is Num key pressed */
|
||||
} tBTA_HH_KEYBD_RPT;
|
||||
|
||||
/* parsed boot mode mouse report */
|
||||
typedef struct {
|
||||
UINT8 mouse_button; /* mouse button is clicked */
|
||||
INT8 delta_x; /* displacement x */
|
||||
INT8 delta_y; /* displacement y */
|
||||
} tBTA_HH_MICE_RPT;
|
||||
|
||||
/* parsed Boot report */
|
||||
typedef struct {
|
||||
tBTA_HH_BOOT_RPT_ID dev_type; /* type of device report */
|
||||
union {
|
||||
tBTA_HH_KEYBD_RPT keybd_rpt; /* keyboard report */
|
||||
tBTA_HH_MICE_RPT mice_rpt; /* mouse report */
|
||||
} data_rpt;
|
||||
} tBTA_HH_BOOT_RPT;
|
||||
|
||||
/* handshake data */
|
||||
typedef struct {
|
||||
tBTA_HH_STATUS status; /* handshake status */
|
||||
UINT8 handle; /* device handle */
|
||||
union {
|
||||
tBTA_HH_PROTO_MODE proto_mode; /* GET_PROTO_EVT :protocol mode */
|
||||
BT_HDR *p_rpt_data; /* GET_RPT_EVT : report data */
|
||||
UINT8 idle_rate; /* GET_IDLE_EVT : idle rate */
|
||||
} rsp_data;
|
||||
|
||||
} tBTA_HH_HSDATA;
|
||||
|
||||
/* union of data associated with HD callback */
|
||||
typedef union {
|
||||
tBTA_HH_DEV_INFO dev_info; /* BTA_HH_ADD_DEV_EVT, BTA_HH_RMV_DEV_EVT */
|
||||
tBTA_HH_CONN conn; /* BTA_HH_OPEN_EVT */
|
||||
tBTA_HH_CBDATA dev_status; /* BTA_HH_CLOSE_EVT,
|
||||
BTA_HH_SET_PROTO_EVT
|
||||
BTA_HH_SET_RPT_EVT
|
||||
BTA_HH_SET_IDLE_EVT
|
||||
BTA_HH_UPDATE_SCPP_EVT */
|
||||
|
||||
tBTA_HH_STATUS status; /* BTA_HH_ENABLE_EVT */
|
||||
tBTA_HH_DEV_DSCP_INFO dscp_info; /* BTA_HH_GET_DSCP_EVT */
|
||||
tBTA_HH_HSDATA hs_data; /* GET_ transaction callback
|
||||
BTA_HH_GET_RPT_EVT
|
||||
BTA_HH_GET_PROTO_EVT
|
||||
BTA_HH_GET_IDLE_EVT */
|
||||
} tBTA_HH;
|
||||
|
||||
/* BTA HH callback function */
|
||||
typedef void (tBTA_HH_CBACK) (tBTA_HH_EVT event, tBTA_HH *p_data);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** External Function Declarations
|
||||
*****************************************************************************/
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhRegister
|
||||
**
|
||||
** Description This function enable HID host and registers HID-Host with
|
||||
** lower layers.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhEnable(tBTA_SEC sec_mask, tBTA_HH_CBACK *p_cback);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhDeregister
|
||||
**
|
||||
** Description This function is called when the host is about power down.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhDisable(void);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhOpen
|
||||
**
|
||||
** Description This function is called to start an inquiry and read SDP
|
||||
** record of responding devices; connect to a device if only
|
||||
** one active HID device is found.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhOpen (BD_ADDR dev_bda, tBTA_HH_PROTO_MODE mode,
|
||||
tBTA_SEC sec_mask);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhClose
|
||||
**
|
||||
** Description This function disconnects the device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhClose(UINT8 dev_handle);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSetProtoMode
|
||||
**
|
||||
** Description This function set the protocol mode at specified HID handle
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhSetProtoMode(UINT8 handle, tBTA_HH_PROTO_MODE t_type);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetProtoMode
|
||||
**
|
||||
** Description This function get the protocol mode of a specified HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhGetProtoMode(UINT8 dev_handle);
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSetReport
|
||||
**
|
||||
** Description send SET_REPORT to device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhSetReport(UINT8 dev_handle, tBTA_HH_RPT_TYPE r_type,
|
||||
BT_HDR *p_data);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetReport
|
||||
**
|
||||
** Description Send a GET_REPORT to HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhGetReport(UINT8 dev_handle, tBTA_HH_RPT_TYPE r_type,
|
||||
UINT8 rpt_id, UINT16 buf_size);
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSetIdle
|
||||
**
|
||||
** Description send SET_IDLE to device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhSetIdle(UINT8 dev_handle, UINT16 idle_rate);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetIdle
|
||||
**
|
||||
** Description Send a GET_IDLE to HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhGetIdle(UINT8 dev_handle);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSendCtrl
|
||||
**
|
||||
** Description Send HID_CONTROL request to a HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhSendCtrl(UINT8 dev_handle,
|
||||
tBTA_HH_TRANS_CTRL_TYPE c_type);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSetIdle
|
||||
**
|
||||
** Description send SET_IDLE to device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhSetIdle(UINT8 dev_handle, UINT16 idle_rate);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetIdle
|
||||
**
|
||||
** Description Send a GET_IDLE from HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhGetIdle(UINT8 dev_handle);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSendData
|
||||
**
|
||||
** Description Send DATA transaction to a HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhSendData(UINT8 dev_handle, BD_ADDR dev_bda, BT_HDR *p_buf);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetDscpInfo
|
||||
**
|
||||
** Description Get report descriptor of the device
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhGetDscpInfo(UINT8 dev_handle);
|
||||
|
||||
/*******************************************************************************
|
||||
** Function BTA_HhAddDev
|
||||
**
|
||||
** Description Add a virtually cabled device into HID-Host device list
|
||||
** to manage and assign a device handle for future API call,
|
||||
** host applciation call this API at start-up to initialize its
|
||||
** virtually cabled devices.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhAddDev(BD_ADDR bda, tBTA_HH_ATTR_MASK attr_mask,
|
||||
UINT8 sub_class, UINT8 app_id,
|
||||
tBTA_HH_DEV_DSCP_INFO dscp_info);
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhRemoveDev
|
||||
**
|
||||
** Description Remove a device from the HID host devices list.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhRemoveDev(UINT8 dev_handle );
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Parsing Utility Functions
|
||||
**
|
||||
*******************************************************************************/
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhParseBootRpt
|
||||
**
|
||||
** Description This utility function parse a boot mode report.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhParseBootRpt(tBTA_HH_BOOT_RPT *p_data, UINT8 *p_report,
|
||||
UINT16 report_len);
|
||||
|
||||
#if BTA_HH_LE_INCLUDED == TRUE
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhUpdateLeScanParam
|
||||
**
|
||||
** Description Update the scan paramteters if connected to a LE hid device as
|
||||
** report host.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhUpdateLeScanParam(UINT8 dev_handle, UINT16 scan_int, UINT16 scan_win);
|
||||
#endif
|
||||
/* test commands */
|
||||
extern void bta_hh_le_hid_read_rpt_clt_cfg(BD_ADDR bd_addr, UINT8 rpt_id);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BTA_HH_API_H */
|
||||
132
components/bt/bluedroid/bta/include/bta_hh_co.h
Normal file
132
components/bt/bluedroid/bta/include/bta_hh_co.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the interface file for hid host call-out functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_HH_CO_H
|
||||
#define BTA_HH_CO_H
|
||||
|
||||
#include "bta_hh_api.h"
|
||||
|
||||
typedef struct {
|
||||
UINT16 rpt_uuid;
|
||||
UINT8 rpt_id;
|
||||
tBTA_HH_RPT_TYPE rpt_type;
|
||||
UINT8 inst_id;
|
||||
UINT8 prop;
|
||||
} tBTA_HH_RPT_CACHE_ENTRY;
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_co_data
|
||||
**
|
||||
** Description This callout function is executed by HH when data is received
|
||||
** in interupt channel.
|
||||
**
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_hh_co_data(UINT8 dev_handle, UINT8 *p_rpt, UINT16 len,
|
||||
tBTA_HH_PROTO_MODE mode, UINT8 sub_class,
|
||||
UINT8 ctry_code, BD_ADDR peer_addr, UINT8 app_id);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_co_open
|
||||
**
|
||||
** Description This callout function is executed by HH when connection is
|
||||
** opened, and application may do some device specific
|
||||
** initialization.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_hh_co_open(UINT8 dev_handle, UINT8 sub_class,
|
||||
UINT16 attr_mask, UINT8 app_id);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_co_close
|
||||
**
|
||||
** Description This callout function is executed by HH when connection is
|
||||
** closed, and device specific finalizatio nmay be needed.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_hh_co_close(UINT8 dev_handle, UINT8 app_id);
|
||||
|
||||
#if (BLE_INCLUDED == TRUE && BTA_HH_LE_INCLUDED == TRUE)
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_le_co_rpt_info
|
||||
**
|
||||
** Description This callout function is to convey the report information on
|
||||
** a HOGP device to the application. Application can save this
|
||||
** information in NV if device is bonded and load it back when
|
||||
** stack reboot.
|
||||
**
|
||||
** Parameters remote_bda - remote device address
|
||||
** p_entry - report entry pointer
|
||||
** app_id - application id
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_hh_le_co_rpt_info(BD_ADDR remote_bda,
|
||||
tBTA_HH_RPT_CACHE_ENTRY *p_entry,
|
||||
UINT8 app_id);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_le_co_cache_load
|
||||
**
|
||||
** Description This callout function is to request the application to load the
|
||||
** cached HOGP report if there is any. When cache reading is completed,
|
||||
** bta_hh_le_ci_cache_load() is called by the application.
|
||||
**
|
||||
** Parameters remote_bda - remote device address
|
||||
** p_num_rpt: number of cached report
|
||||
** app_id - application id
|
||||
**
|
||||
** Returns the acched report array
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern tBTA_HH_RPT_CACHE_ENTRY *bta_hh_le_co_cache_load (BD_ADDR remote_bda,
|
||||
UINT8 *p_num_rpt,
|
||||
UINT8 app_id);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_le_co_reset_rpt_cache
|
||||
**
|
||||
** Description This callout function is to reset the HOGP device cache.
|
||||
**
|
||||
** Parameters remote_bda - remote device address
|
||||
**
|
||||
** Returns none
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_hh_le_co_reset_rpt_cache (BD_ADDR remote_bda, UINT8 app_id);
|
||||
|
||||
#endif /* #if (BLE_INCLUDED == TRUE && BTA_HH_LE_INCLUDED == TRUE) */
|
||||
#endif /* BTA_HH_CO_H */
|
||||
142
components/bt/bluedroid/bta/include/bta_sdp_api.h
Normal file
142
components/bt/bluedroid/bta/include/bta_sdp_api.h
Normal file
@@ -0,0 +1,142 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the public interface file for the BTA SDP I/F
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_SDP_API_H
|
||||
#define BTA_SDP_API_H
|
||||
|
||||
#include "bt_sdp.h"
|
||||
#include "bt_target.h"
|
||||
#include "bt_types.h"
|
||||
#include "bta_api.h"
|
||||
#include "btm_api.h"
|
||||
|
||||
/* status values */
|
||||
#define BTA_SDP_SUCCESS 0 /* Successful operation. */
|
||||
#define BTA_SDP_FAILURE 1 /* Generic failure. */
|
||||
#define BTA_SDP_BUSY 2 /* Temporarily can not handle this request. */
|
||||
|
||||
typedef UINT8 tBTA_SDP_STATUS;
|
||||
|
||||
/* SDP I/F callback events */
|
||||
/* events received by tBTA_SDP_DM_CBACK */
|
||||
#define BTA_SDP_ENABLE_EVT 0 /* SDP service i/f enabled*/
|
||||
#define BTA_SDP_SEARCH_EVT 1 /* SDP Service started */
|
||||
#define BTA_SDP_SEARCH_COMP_EVT 2 /* SDP search complete */
|
||||
#define BTA_SDP_CREATE_RECORD_USER_EVT 3 /* SDP search complete */
|
||||
#define BTA_SDP_REMOVE_RECORD_USER_EVT 4 /* SDP search complete */
|
||||
#define BTA_SDP_MAX_EVT 5 /* max number of SDP events */
|
||||
|
||||
#define BTA_SDP_MAX_RECORDS 15
|
||||
|
||||
typedef UINT16 tBTA_SDP_EVT;
|
||||
|
||||
/* data associated with BTA_SDP_DISCOVERY_COMP_EVT */
|
||||
typedef struct {
|
||||
tBTA_SDP_STATUS status;
|
||||
BD_ADDR remote_addr;
|
||||
tBT_UUID uuid;
|
||||
int record_count;
|
||||
bluetooth_sdp_record records[BTA_SDP_MAX_RECORDS];
|
||||
} tBTA_SDP_SEARCH_COMP;
|
||||
|
||||
typedef union {
|
||||
tBTA_SDP_STATUS status; /* BTA_SDP_SEARCH_EVT */
|
||||
tBTA_SDP_SEARCH_COMP sdp_search_comp; /* BTA_SDP_SEARCH_COMP_EVT */
|
||||
} tBTA_SDP;
|
||||
|
||||
/* SDP DM Interface callback */
|
||||
typedef void (tBTA_SDP_DM_CBACK)(tBTA_SDP_EVT event, tBTA_SDP *p_data, void *user_data);
|
||||
|
||||
/* MCE configuration structure */
|
||||
typedef struct {
|
||||
UINT16 sdp_db_size; /* The size of p_sdp_db */
|
||||
tSDP_DISCOVERY_DB *p_sdp_db; /* The data buffer to keep SDP database */
|
||||
} tBTA_SDP_CFG;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_SdpEnable
|
||||
**
|
||||
** Description Enable the SDP I/F service. When the enable
|
||||
** operation is complete the callback function will be
|
||||
** called with a BTA_SDP_ENABLE_EVT. This function must
|
||||
** be called before other functions in the MCE API are
|
||||
** called.
|
||||
**
|
||||
** Returns BTA_SDP_SUCCESS if successful.
|
||||
** BTA_SDP_FAIL if internal failure.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern tBTA_SDP_STATUS BTA_SdpEnable(tBTA_SDP_DM_CBACK *p_cback);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_SdpSearch
|
||||
**
|
||||
** Description Start a search for sdp records for a specific BD_ADDR with a
|
||||
** specific profile uuid.
|
||||
** When the search operation is completed, the callback function
|
||||
** will be called with a BTA_SDP_SEARCH_EVT.
|
||||
** Returns BTA_SDP_SUCCESS if successful.
|
||||
** BTA_SDP_FAIL if internal failure.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern tBTA_SDP_STATUS BTA_SdpSearch(BD_ADDR bd_addr, tSDP_UUID *uuid);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_SdpCreateRecordByUser
|
||||
**
|
||||
** Description This function is used to request a callback to create a SDP
|
||||
** record. The registered callback will be called with event
|
||||
** BTA_SDP_CREATE_RECORD_USER_EVT.
|
||||
**
|
||||
** Returns BTA_SDP_SUCCESS, if the request is being processed.
|
||||
** BTA_SDP_FAILURE, otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern tBTA_SDP_STATUS BTA_SdpCreateRecordByUser(void *user_data);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_SdpRemoveRecordByUser
|
||||
**
|
||||
** Description This function is used to request a callback to remove a SDP
|
||||
** record. The registered callback will be called with event
|
||||
** BTA_SDP_REMOVE_RECORD_USER_EVT.
|
||||
**
|
||||
** Returns BTA_SDP_SUCCESS, if the request is being processed.
|
||||
** BTA_SDP_FAILURE, otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern tBTA_SDP_STATUS BTA_SdpRemoveRecordByUser(void *user_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BTA_SDP_API_H */
|
||||
282
components/bt/bluedroid/bta/include/bta_sys.h
Normal file
282
components/bt/bluedroid/bta/include/bta_sys.h
Normal file
@@ -0,0 +1,282 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the public interface file for the BTA system manager.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_SYS_H
|
||||
#define BTA_SYS_H
|
||||
|
||||
#include "bt_target.h"
|
||||
#include "gki.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and data types
|
||||
*****************************************************************************/
|
||||
|
||||
/* vendor specific event handler function type */
|
||||
typedef BOOLEAN (tBTA_SYS_VS_EVT_HDLR)(UINT16 evt, void *p);
|
||||
|
||||
/* event handler function type */
|
||||
typedef BOOLEAN (tBTA_SYS_EVT_HDLR)(BT_HDR *p_msg);
|
||||
|
||||
/* disable function type */
|
||||
typedef void (tBTA_SYS_DISABLE)(void);
|
||||
|
||||
|
||||
/* HW modules */
|
||||
enum {
|
||||
BTA_SYS_HW_BLUETOOTH,
|
||||
BTA_SYS_HW_RT,
|
||||
|
||||
BTA_SYS_MAX_HW_MODULES
|
||||
};
|
||||
|
||||
typedef UINT16 tBTA_SYS_HW_MODULE;
|
||||
|
||||
#ifndef BTA_DM_NUM_JV_ID
|
||||
#define BTA_DM_NUM_JV_ID 2
|
||||
#endif
|
||||
|
||||
/* SW sub-systems */
|
||||
#define BTA_ID_SYS 0 /* system manager */
|
||||
/* BLUETOOTH PART - from 0 to BTA_ID_BLUETOOTH_MAX */
|
||||
#define BTA_ID_DM 1 /* device manager */
|
||||
#define BTA_ID_DM_SEARCH 2 /* device manager search */
|
||||
#define BTA_ID_DM_SEC 3 /* device manager security */
|
||||
#define BTA_ID_DG 4 /* data gateway */
|
||||
#define BTA_ID_AG 5 /* audio gateway */
|
||||
#define BTA_ID_OPC 6 /* object push client */
|
||||
#define BTA_ID_OPS 7 /* object push server */
|
||||
#define BTA_ID_FTS 8 /* file transfer server */
|
||||
#define BTA_ID_CT 9 /* cordless telephony terminal */
|
||||
#define BTA_ID_FTC 10 /* file transfer client */
|
||||
#define BTA_ID_SS 11 /* synchronization server */
|
||||
#define BTA_ID_PR 12 /* Printer client */
|
||||
#define BTA_ID_BIC 13 /* Basic Imaging Client */
|
||||
#define BTA_ID_PAN 14 /* Personal Area Networking */
|
||||
#define BTA_ID_BIS 15 /* Basic Imaging Server */
|
||||
#define BTA_ID_ACC 16 /* Advanced Camera Client */
|
||||
#define BTA_ID_SC 17 /* SIM Card Access server */
|
||||
#define BTA_ID_AV 18 /* Advanced audio/video */
|
||||
#define BTA_ID_AVK 19 /* Audio/video sink */
|
||||
#define BTA_ID_HD 20 /* HID Device */
|
||||
#define BTA_ID_CG 21 /* Cordless Gateway */
|
||||
#define BTA_ID_BP 22 /* Basic Printing Client */
|
||||
#define BTA_ID_HH 23 /* Human Interface Device Host */
|
||||
#define BTA_ID_PBS 24 /* Phone Book Access Server */
|
||||
#define BTA_ID_PBC 25 /* Phone Book Access Client */
|
||||
#define BTA_ID_JV 26 /* Java */
|
||||
#define BTA_ID_HS 27 /* Headset */
|
||||
#define BTA_ID_MSE 28 /* Message Server Equipment */
|
||||
#define BTA_ID_MCE 29 /* Message Client Equipment */
|
||||
#define BTA_ID_HL 30 /* Health Device Profile*/
|
||||
#define BTA_ID_GATTC 31 /* GATT Client */
|
||||
#define BTA_ID_GATTS 32 /* GATT Client */
|
||||
#define BTA_ID_SDP 33 /* SDP Client */
|
||||
#define BTA_ID_BLUETOOTH_MAX 34 /* last BT profile */
|
||||
|
||||
/* GENERIC */
|
||||
#define BTA_ID_PRM 38
|
||||
#define BTA_ID_SYSTEM 39 /* platform-specific */
|
||||
#define BTA_ID_SWRAP 40 /* Insight script wrapper */
|
||||
#define BTA_ID_MIP 41 /* Multicase Individual Polling */
|
||||
#define BTA_ID_RT 42 /* Audio Routing module: This module is always on. */
|
||||
|
||||
|
||||
/* JV */
|
||||
#define BTA_ID_JV1 44 /* JV1 */
|
||||
#define BTA_ID_JV2 45 /* JV2 */
|
||||
|
||||
#define BTA_ID_MAX (44 + BTA_DM_NUM_JV_ID)
|
||||
|
||||
typedef UINT8 tBTA_SYS_ID;
|
||||
|
||||
|
||||
#define BTA_SYS_CONN_OPEN 0x00
|
||||
#define BTA_SYS_CONN_CLOSE 0x01
|
||||
#define BTA_SYS_APP_OPEN 0x02
|
||||
#define BTA_SYS_APP_CLOSE 0x03
|
||||
#define BTA_SYS_SCO_OPEN 0x04
|
||||
#define BTA_SYS_SCO_CLOSE 0x05
|
||||
#define BTA_SYS_CONN_IDLE 0x06
|
||||
#define BTA_SYS_CONN_BUSY 0x07
|
||||
|
||||
/* for link policy */
|
||||
#define BTA_SYS_PLCY_SET 0x10 /* set the link policy to the given addr */
|
||||
#define BTA_SYS_PLCY_CLR 0x11 /* clear the link policy to the given addr */
|
||||
#define BTA_SYS_PLCY_DEF_SET 0x12 /* set the default link policy */
|
||||
#define BTA_SYS_PLCY_DEF_CLR 0x13 /* clear the default link policy */
|
||||
#define BTA_SYS_ROLE_CHANGE 0x14 /* role change */
|
||||
|
||||
typedef UINT8 tBTA_SYS_CONN_STATUS;
|
||||
|
||||
/* Bitmask of sys features */
|
||||
#define BTA_SYS_FEAT_PCM2 0x0001
|
||||
#define BTA_SYS_FEAT_PCM2_MASTER 0x0002
|
||||
|
||||
/* tBTA_PREF_ROLES */
|
||||
typedef UINT8 tBTA_SYS_PREF_ROLES;
|
||||
|
||||
/* conn callback for role / low power manager*/
|
||||
typedef void (tBTA_SYS_CONN_CBACK)(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
|
||||
/* conn callback for role / low power manager*/
|
||||
typedef void (tBTA_SYS_SSR_CFG_CBACK)(UINT8 id, UINT8 app_id, UINT16 latency, UINT16 tout);
|
||||
|
||||
#if (BTA_EIR_CANNED_UUID_LIST != TRUE)
|
||||
/* eir callback for adding/removeing UUID */
|
||||
typedef void (tBTA_SYS_EIR_CBACK)(UINT16 uuid16, BOOLEAN adding);
|
||||
#endif
|
||||
|
||||
/* registration structure */
|
||||
typedef struct {
|
||||
tBTA_SYS_EVT_HDLR *evt_hdlr;
|
||||
tBTA_SYS_DISABLE *disable;
|
||||
} tBTA_SYS_REG;
|
||||
|
||||
/* data type to send events to BTA SYS HW manager */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_SYS_HW_MODULE hw_module;
|
||||
} tBTA_SYS_HW_MSG;
|
||||
|
||||
/*****************************************************************************
|
||||
** Global data
|
||||
*****************************************************************************/
|
||||
|
||||
/* trace level */
|
||||
extern UINT8 appl_trace_level;
|
||||
|
||||
/*****************************************************************************
|
||||
** Macros
|
||||
*****************************************************************************/
|
||||
|
||||
/* Calculate start of event enumeration; id is top 8 bits of event */
|
||||
#define BTA_SYS_EVT_START(id) ((id) << 8)
|
||||
|
||||
/*****************************************************************************
|
||||
** events for BTA SYS HW manager
|
||||
*****************************************************************************/
|
||||
|
||||
/* events sent to SYS HW manager - must be kept synchronized with tables in bta_sys_main.c */
|
||||
enum {
|
||||
/* device manager local device API events */
|
||||
BTA_SYS_API_ENABLE_EVT = BTA_SYS_EVT_START(BTA_ID_SYS),
|
||||
BTA_SYS_EVT_ENABLED_EVT,
|
||||
BTA_SYS_EVT_STACK_ENABLED_EVT,
|
||||
BTA_SYS_API_DISABLE_EVT,
|
||||
BTA_SYS_EVT_DISABLED_EVT,
|
||||
BTA_SYS_ERROR_EVT,
|
||||
|
||||
BTA_SYS_MAX_EVT
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* SYS HW status events - returned by SYS HW manager to other modules. */
|
||||
enum {
|
||||
BTA_SYS_HW_OFF_EVT,
|
||||
BTA_SYS_HW_ON_EVT,
|
||||
BTA_SYS_HW_STARTING_EVT,
|
||||
BTA_SYS_HW_STOPPING_EVT,
|
||||
BTA_SYS_HW_ERROR_EVT
|
||||
|
||||
};
|
||||
typedef UINT8 tBTA_SYS_HW_EVT;
|
||||
|
||||
/* HW enable callback type */
|
||||
typedef void (tBTA_SYS_HW_CBACK)(tBTA_SYS_HW_EVT status);
|
||||
|
||||
/*****************************************************************************
|
||||
** Function declarations
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void bta_sys_init(void);
|
||||
extern void bta_sys_free(void);
|
||||
extern void bta_sys_event(BT_HDR *p_msg);
|
||||
extern void bta_sys_set_trace_level(UINT8 level);
|
||||
extern void bta_sys_register(UINT8 id, const tBTA_SYS_REG *p_reg);
|
||||
extern void bta_sys_deregister(UINT8 id);
|
||||
extern BOOLEAN bta_sys_is_register(UINT8 id);
|
||||
extern UINT16 bta_sys_get_sys_features(void);
|
||||
extern void bta_sys_sendmsg(void *p_msg);
|
||||
extern void bta_sys_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout_ms);
|
||||
extern void bta_sys_stop_timer(TIMER_LIST_ENT *p_tle);
|
||||
extern void bta_sys_disable(tBTA_SYS_HW_MODULE module);
|
||||
extern UINT32 bta_sys_get_remaining_ticks(TIMER_LIST_ENT *p_target_tle);
|
||||
|
||||
extern void bta_sys_hw_register( tBTA_SYS_HW_MODULE module, tBTA_SYS_HW_CBACK *cback);
|
||||
extern void bta_sys_hw_unregister( tBTA_SYS_HW_MODULE module );
|
||||
|
||||
|
||||
extern void bta_sys_rm_register(tBTA_SYS_CONN_CBACK *p_cback);
|
||||
extern void bta_sys_pm_register(tBTA_SYS_CONN_CBACK *p_cback);
|
||||
|
||||
extern void bta_sys_policy_register(tBTA_SYS_CONN_CBACK *p_cback);
|
||||
extern void bta_sys_sco_register(tBTA_SYS_CONN_CBACK *p_cback);
|
||||
|
||||
|
||||
extern void bta_sys_conn_open(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
extern void bta_sys_conn_close(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
extern void bta_sys_app_open(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
extern void bta_sys_app_close(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
extern void bta_sys_sco_open(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
extern void bta_sys_sco_close(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
extern void bta_sys_sco_use(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
extern void bta_sys_sco_unuse(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
extern void bta_sys_idle(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
extern void bta_sys_busy(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
extern void bta_sys_ssr_cfg_register(tBTA_SYS_SSR_CFG_CBACK *p_cback);
|
||||
extern void bta_sys_chg_ssr_config (UINT8 id, UINT8 app_id, UINT16 max_latency, UINT16 min_tout);
|
||||
#endif
|
||||
|
||||
extern void bta_sys_role_chg_register(tBTA_SYS_CONN_CBACK *p_cback);
|
||||
extern void bta_sys_notify_role_chg(BD_ADDR_PTR p_bda, UINT8 new_role, UINT8 hci_status);
|
||||
extern void bta_sys_collision_register(UINT8 bta_id, tBTA_SYS_CONN_CBACK *p_cback);
|
||||
extern void bta_sys_notify_collision (BD_ADDR_PTR p_bda);
|
||||
|
||||
#if (BTA_EIR_CANNED_UUID_LIST != TRUE)
|
||||
extern void bta_sys_eir_register(tBTA_SYS_EIR_CBACK *p_cback);
|
||||
extern void bta_sys_add_uuid(UINT16 uuid16);
|
||||
extern void bta_sys_remove_uuid(UINT16 uuid16);
|
||||
#else
|
||||
#define bta_sys_eir_register(ut)
|
||||
#define bta_sys_add_uuid(ut)
|
||||
#define bta_sys_remove_uuid(ut)
|
||||
#endif
|
||||
|
||||
extern void bta_sys_set_policy (UINT8 id, UINT8 policy, BD_ADDR peer_addr);
|
||||
extern void bta_sys_clear_policy (UINT8 id, UINT8 policy, BD_ADDR peer_addr);
|
||||
extern void bta_sys_set_default_policy (UINT8 id, UINT8 policy);
|
||||
extern void bta_sys_clear_default_policy (UINT8 id, UINT8 policy);
|
||||
extern BOOLEAN bta_sys_vs_hdl(UINT16 evt, void *p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BTA_SYS_H */
|
||||
169
components/bt/bluedroid/bta/include/utl.h
Normal file
169
components/bt/bluedroid/bta/include/utl.h
Normal file
@@ -0,0 +1,169 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Basic utility functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef UTL_H
|
||||
#define UTL_H
|
||||
|
||||
#include "bt_types.h"
|
||||
// #include "bt_utils.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
/*** class of device settings ***/
|
||||
#define BTA_UTL_SET_COD_MAJOR_MINOR 0x01
|
||||
#define BTA_UTL_SET_COD_SERVICE_CLASS 0x02 /* only set the bits in the input */
|
||||
#define BTA_UTL_CLR_COD_SERVICE_CLASS 0x04
|
||||
#define BTA_UTL_SET_COD_ALL 0x08 /* take service class as the input (may clear some set bits!!) */
|
||||
#define BTA_UTL_INIT_COD 0x0a
|
||||
|
||||
/*****************************************************************************
|
||||
** Type Definitions
|
||||
*****************************************************************************/
|
||||
|
||||
/** for utl_set_device_class() **/
|
||||
typedef struct {
|
||||
UINT8 minor;
|
||||
UINT8 major;
|
||||
UINT16 service;
|
||||
} tBTA_UTL_COD;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
** External Function Declarations
|
||||
*****************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_str2int
|
||||
**
|
||||
** Description This utility function converts a character string to an
|
||||
** integer. Acceptable values in string are 0-9. If invalid
|
||||
** string or string value too large, -1 is returned.
|
||||
**
|
||||
**
|
||||
** Returns Integer value or -1 on error.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern INT16 utl_str2int(const char *p_s);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_strucmp
|
||||
**
|
||||
** Description This utility function compares two strings in uppercase.
|
||||
** String p_s must be uppercase. String p_t is converted to
|
||||
** uppercase if lowercase. If p_s ends first, the substring
|
||||
** match is counted as a match.
|
||||
**
|
||||
**
|
||||
** Returns 0 if strings match, nonzero otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern int utl_strucmp(const char *p_s, const char *p_t);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_itoa
|
||||
**
|
||||
** Description This utility function converts a UINT16 to a string. The
|
||||
** string is NULL-terminated. The length of the string is
|
||||
** returned.
|
||||
**
|
||||
**
|
||||
** Returns Length of string.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern UINT8 utl_itoa(UINT16 i, char *p_s);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_freebuf
|
||||
**
|
||||
** Description This function calls GKI_freebuf to free the buffer passed
|
||||
** in, if buffer pointer is not NULL, and also initializes
|
||||
** buffer pointer to NULL.
|
||||
**
|
||||
**
|
||||
** Returns Nothing.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void utl_freebuf(void **p);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_set_device_class
|
||||
**
|
||||
** Description This function updates the local Device Class.
|
||||
**
|
||||
** Parameters:
|
||||
** p_cod - Pointer to the device class to set to
|
||||
**
|
||||
** cmd - the fields of the device class to update.
|
||||
** BTA_UTL_SET_COD_MAJOR_MINOR, - overwrite major, minor class
|
||||
** BTA_UTL_SET_COD_SERVICE_CLASS - set the bits in the input
|
||||
** BTA_UTL_CLR_COD_SERVICE_CLASS - clear the bits in the input
|
||||
** BTA_UTL_SET_COD_ALL - overwrite major, minor, set the bits in service class
|
||||
** BTA_UTL_INIT_COD - overwrite major, minor, and service class
|
||||
**
|
||||
** Returns TRUE if successful, Otherwise FALSE
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern BOOLEAN utl_set_device_class(tBTA_UTL_COD *p_cod, UINT8 cmd);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_isintstr
|
||||
**
|
||||
** Description This utility function checks if the given string is an
|
||||
** integer string or not
|
||||
**
|
||||
**
|
||||
** Returns TRUE if successful, Otherwise FALSE
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern BOOLEAN utl_isintstr(const char *p_s);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_isdialstr
|
||||
**
|
||||
** Description This utility function checks if the given string contains
|
||||
** only dial digits or not
|
||||
**
|
||||
**
|
||||
** Returns TRUE if successful, Otherwise FALSE
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern BOOLEAN utl_isdialstr(const char *p_s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* UTL_H */
|
||||
77
components/bt/bluedroid/bta/sdp/bta_sdp.c
Normal file
77
components/bt/bluedroid/bta/sdp/bta_sdp.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the main implementation file for the BTA MCE I/F
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "bta_api.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_sdp_api.h"
|
||||
#include "bta_sdp_int.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and types
|
||||
*****************************************************************************/
|
||||
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
tBTA_SDP_CB bta_sdp_cb;
|
||||
#endif
|
||||
|
||||
/* state machine action enumeration list */
|
||||
#define BTA_SDP_NUM_ACTIONS (BTA_SDP_MAX_INT_EVT & 0x00ff)
|
||||
|
||||
/* type for action functions */
|
||||
typedef void (*tBTA_SDP_ACTION)(tBTA_SDP_MSG *p_data);
|
||||
|
||||
/* action function list */
|
||||
const tBTA_SDP_ACTION bta_sdp_action[] = {
|
||||
bta_sdp_enable, /* BTA_SDP_API_ENABLE_EVT */
|
||||
bta_sdp_search, /* BTA_SDP_API_SEARCH_EVT */
|
||||
bta_sdp_create_record, /* BTA_SDP_API_CREATE_RECORD_USER_EVT */
|
||||
bta_sdp_remove_record, /* BTA_SDP_API_REMOVE_RECORD_USER_EVT */
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
** Function bta_sdp_sm_execute
|
||||
**
|
||||
** Description State machine event handling function for SDP search
|
||||
**
|
||||
** Returns void
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_sdp_sm_execute(BT_HDR *p_msg)
|
||||
{
|
||||
if (p_msg == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN ret = FALSE;
|
||||
UINT16 action = (p_msg->event & 0x00ff);
|
||||
|
||||
/* execute action functions */
|
||||
if (action < BTA_SDP_NUM_ACTIONS) {
|
||||
(*bta_sdp_action[action])((tBTA_SDP_MSG *)p_msg);
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
545
components/bt/bluedroid/bta/sdp/bta_sdp_act.c
Normal file
545
components/bt/bluedroid/bta/sdp/bta_sdp_act.c
Normal file
@@ -0,0 +1,545 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
* This file contains action functions for SDP search.
|
||||
******************************************************************************/
|
||||
|
||||
// #include <hardware/bluetooth.h>
|
||||
#include "bt_sdp.h"
|
||||
// #include <arpa/inet.h>
|
||||
#include "bt_defs.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "allocator.h"
|
||||
#include "bt_types.h"
|
||||
#include "gki.h"
|
||||
#include "utl.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_api.h"
|
||||
#include "bta_sdp_api.h"
|
||||
#include "bta_sdp_int.h"
|
||||
#include "btm_api.h"
|
||||
#include "btm_int.h"
|
||||
#include "sdp_api.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
|
||||
static const uint8_t UUID_OBEX_OBJECT_PUSH[] = {0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
|
||||
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
|
||||
};
|
||||
static const uint8_t UUID_PBAP_PSE[] = {0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00,
|
||||
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
|
||||
};
|
||||
static const uint8_t UUID_MAP_MAS[] = {0x00, 0x00, 0x11, 0x32, 0x00, 0x00, 0x10, 0x00,
|
||||
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
|
||||
};
|
||||
static const uint8_t UUID_MAP_MNS[] = {0x00, 0x00, 0x11, 0x33, 0x00, 0x00, 0x10, 0x00,
|
||||
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
|
||||
};
|
||||
static const uint8_t UUID_SPP[] = {0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x10, 0x00,
|
||||
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
|
||||
};
|
||||
static const uint8_t UUID_SAP[] = {0x00, 0x00, 0x11, 0x2D, 0x00, 0x00, 0x10, 0x00,
|
||||
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
|
||||
};
|
||||
// TODO:
|
||||
// Both the fact that the UUIDs are declared in multiple places, plus the fact
|
||||
// that there is a mess of UUID comparison and shortening methods will have to
|
||||
// be fixed.
|
||||
// The btcore->uuid module should be used for all instances.
|
||||
|
||||
#define UUID_MAX_LENGTH 16
|
||||
#define IS_UUID(u1,u2) !memcmp(u1,u2,UUID_MAX_LENGTH)
|
||||
|
||||
static inline tBT_UUID shorten_sdp_uuid(const tBT_UUID *u)
|
||||
{
|
||||
static uint8_t bt_base_uuid[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
|
||||
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
|
||||
};
|
||||
|
||||
APPL_TRACE_DEBUG("%s() - uuid len:%d\n", __func__, u->len);
|
||||
if (u->len != 16) {
|
||||
return *u;
|
||||
}
|
||||
|
||||
if (memcmp(&u->uu.uuid128[4], &bt_base_uuid[4], 12) != 0) {
|
||||
return *u;
|
||||
}
|
||||
|
||||
tBT_UUID su;
|
||||
memset(&su, 0, sizeof(su));
|
||||
if (u->uu.uuid128[0] == 0 && u->uu.uuid128[1] == 0) {
|
||||
su.len = 2;
|
||||
uint16_t u16;
|
||||
memcpy(&u16, &u->uu.uuid128[2], sizeof(u16));
|
||||
su.uu.uuid16 = ntohs(u16);
|
||||
} else {
|
||||
su.len = 4;
|
||||
uint32_t u32;
|
||||
memcpy(&u32, &u->uu.uuid128[0], sizeof(u32));
|
||||
su.uu.uuid32 = ntohl(u32);
|
||||
}
|
||||
return su;
|
||||
}
|
||||
|
||||
static void bta_create_mns_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
|
||||
{
|
||||
tSDP_DISC_ATTR *p_attr;
|
||||
tSDP_PROTOCOL_ELEM pe;
|
||||
UINT16 pversion = 0;
|
||||
record->mns.hdr.type = SDP_TYPE_MAP_MNS;
|
||||
record->mns.hdr.service_name_length = 0;
|
||||
record->mns.hdr.service_name = NULL;
|
||||
record->mns.hdr.rfcomm_channel_number = 0;
|
||||
record->mns.hdr.l2cap_psm = -1;
|
||||
record->mns.hdr.profile_version = 0;
|
||||
record->mns.supported_features = 0x0000001F; //default value if not found
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES)) != NULL) {
|
||||
record->mns.supported_features = p_attr->attr_value.v.u32;
|
||||
}
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL) {
|
||||
record->mns.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
|
||||
record->mns.hdr.service_name = (char *)p_attr->attr_value.v.array;
|
||||
}
|
||||
|
||||
if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_MAP_PROFILE, &pversion)) {
|
||||
record->mns.hdr.profile_version = pversion;
|
||||
}
|
||||
|
||||
if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
|
||||
record->mns.hdr.rfcomm_channel_number = pe.params[0];
|
||||
}
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM)) != NULL) {
|
||||
record->mns.hdr.l2cap_psm = p_attr->attr_value.v.u16;
|
||||
}
|
||||
}
|
||||
|
||||
static void bta_create_mas_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
|
||||
{
|
||||
tSDP_DISC_ATTR *p_attr;
|
||||
tSDP_PROTOCOL_ELEM pe;
|
||||
UINT16 pversion = -1;
|
||||
|
||||
record->mas.hdr.type = SDP_TYPE_MAP_MAS;
|
||||
record->mas.hdr.service_name_length = 0;
|
||||
record->mas.hdr.service_name = NULL;
|
||||
record->mas.hdr.rfcomm_channel_number = 0;
|
||||
record->mas.hdr.l2cap_psm = -1;
|
||||
record->mas.hdr.profile_version = 0;
|
||||
record->mas.mas_instance_id = 0;
|
||||
record->mas.supported_features = 0x0000001F;
|
||||
record->mas.supported_message_types = 0;
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAS_INSTANCE_ID)) != NULL) {
|
||||
record->mas.mas_instance_id = p_attr->attr_value.v.u8;
|
||||
}
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_MSG_TYPE)) != NULL) {
|
||||
record->mas.supported_message_types = p_attr->attr_value.v.u8;
|
||||
}
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES)) != NULL) {
|
||||
record->mas.supported_features = p_attr->attr_value.v.u32;
|
||||
}
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL) {
|
||||
record->mas.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
|
||||
record->mas.hdr.service_name = (char *)p_attr->attr_value.v.array;
|
||||
}
|
||||
|
||||
if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_MAP_PROFILE, &pversion)) {
|
||||
record->mas.hdr.profile_version = pversion;
|
||||
}
|
||||
|
||||
if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
|
||||
record->mas.hdr.rfcomm_channel_number = pe.params[0];
|
||||
}
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM)) != NULL) {
|
||||
record->mas.hdr.l2cap_psm = p_attr->attr_value.v.u16;
|
||||
}
|
||||
}
|
||||
|
||||
static void bta_create_pse_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
|
||||
{
|
||||
tSDP_DISC_ATTR *p_attr;
|
||||
UINT16 pversion;
|
||||
tSDP_PROTOCOL_ELEM pe;
|
||||
|
||||
record->pse.hdr.type = SDP_TYPE_PBAP_PSE;
|
||||
record->pse.hdr.service_name_length = 0;
|
||||
record->pse.hdr.service_name = NULL;
|
||||
record->pse.hdr.rfcomm_channel_number = 0;
|
||||
record->pse.hdr.l2cap_psm = -1;
|
||||
record->pse.hdr.profile_version = 0;
|
||||
record->pse.supported_features = 0x00000003;
|
||||
record->pse.supported_repositories = 0;
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_REPOSITORIES)) != NULL) {
|
||||
record->pse.supported_repositories = p_attr->attr_value.v.u8;
|
||||
}
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PBAP_SUPPORTED_FEATURES)) != NULL) {
|
||||
record->pse.supported_features = p_attr->attr_value.v.u32;
|
||||
}
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL) {
|
||||
record->pse.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
|
||||
record->pse.hdr.service_name = (char *)p_attr->attr_value.v.array;
|
||||
}
|
||||
|
||||
if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_PHONE_ACCESS, &pversion)) {
|
||||
record->pse.hdr.profile_version = pversion;
|
||||
}
|
||||
|
||||
if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
|
||||
record->pse.hdr.rfcomm_channel_number = pe.params[0];
|
||||
}
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM)) != NULL) {
|
||||
record->pse.hdr.l2cap_psm = p_attr->attr_value.v.u16;
|
||||
}
|
||||
}
|
||||
|
||||
static void bta_create_ops_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
|
||||
{
|
||||
tSDP_DISC_ATTR *p_attr, *p_sattr;
|
||||
tSDP_PROTOCOL_ELEM pe;
|
||||
UINT16 pversion = -1;
|
||||
|
||||
record->ops.hdr.type = SDP_TYPE_OPP_SERVER;
|
||||
record->ops.hdr.service_name_length = 0;
|
||||
record->ops.hdr.service_name = NULL;
|
||||
record->ops.hdr.rfcomm_channel_number = 0;
|
||||
record->ops.hdr.l2cap_psm = -1;
|
||||
record->ops.hdr.profile_version = 0;
|
||||
record->ops.supported_formats_list_len = 0;
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL) {
|
||||
record->ops.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
|
||||
record->ops.hdr.service_name = (char *)p_attr->attr_value.v.array;
|
||||
}
|
||||
|
||||
if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_OBEX_OBJECT_PUSH, &pversion)) {
|
||||
record->ops.hdr.profile_version = pversion;
|
||||
}
|
||||
|
||||
if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
|
||||
record->ops.hdr.rfcomm_channel_number = pe.params[0];
|
||||
}
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM)) != NULL) {
|
||||
record->ops.hdr.l2cap_psm = p_attr->attr_value.v.u16;
|
||||
}
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FORMATS_LIST)) != NULL) {
|
||||
/* Safety check - each entry should itself be a sequence */
|
||||
if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE) {
|
||||
record->ops.supported_formats_list_len = 0;
|
||||
APPL_TRACE_ERROR("%s() - supported_formats_list - wrong attribute length/type:"
|
||||
" 0x%02x - expected 0x06", __func__, p_attr->attr_len_type);
|
||||
} else {
|
||||
int count = 0;
|
||||
/* 1 byte for type/length 1 byte for value */
|
||||
record->ops.supported_formats_list_len = SDP_DISC_ATTR_LEN(p_attr->attr_len_type) / 2;
|
||||
|
||||
/* Extract each value into */
|
||||
for (p_sattr = p_attr->attr_value.v.p_sub_attr;
|
||||
p_sattr != NULL; p_sattr = p_sattr->p_next_attr) {
|
||||
if ((SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == UINT_DESC_TYPE)
|
||||
&& (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) == 1)) {
|
||||
if (count == sizeof(record->ops.supported_formats_list)) {
|
||||
APPL_TRACE_ERROR("%s() - supported_formats_list - count overflow - "
|
||||
"too many sub attributes!!\n", __func__);
|
||||
/* If you hit this, new formats have been added,
|
||||
* update SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH */
|
||||
break;
|
||||
}
|
||||
record->ops.supported_formats_list[count] = p_sattr->attr_value.v.u8;
|
||||
count++;
|
||||
} else {
|
||||
APPL_TRACE_ERROR("%s() - supported_formats_list - wrong sub attribute "
|
||||
"length/type: 0x%02x - expected 0x80", __func__,
|
||||
p_sattr->attr_len_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (record->ops.supported_formats_list_len != count) {
|
||||
APPL_TRACE_WARNING("%s() - supported_formats_list - Length of attribute different "
|
||||
"from the actual number of sub-attributes in the sequence "
|
||||
"att-length: %d - number of elements: %d\n", __func__,
|
||||
record->ops.supported_formats_list_len , count);
|
||||
|
||||
}
|
||||
record->ops.supported_formats_list_len = count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bta_create_sap_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
|
||||
{
|
||||
tSDP_DISC_ATTR *p_attr;
|
||||
tSDP_PROTOCOL_ELEM pe;
|
||||
UINT16 pversion = -1;
|
||||
|
||||
record->sap.hdr.type = SDP_TYPE_MAP_MAS;
|
||||
record->sap.hdr.service_name_length = 0;
|
||||
record->sap.hdr.service_name = NULL;
|
||||
record->sap.hdr.rfcomm_channel_number = 0;
|
||||
record->sap.hdr.l2cap_psm = -1;
|
||||
record->sap.hdr.profile_version = 0;
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL) {
|
||||
record->sap.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
|
||||
record->sap.hdr.service_name = (char *)p_attr->attr_value.v.array;
|
||||
}
|
||||
|
||||
if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_SAP, &pversion)) {
|
||||
record->sap.hdr.profile_version = pversion;
|
||||
}
|
||||
|
||||
if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
|
||||
record->sap.hdr.rfcomm_channel_number = pe.params[0];
|
||||
}
|
||||
}
|
||||
|
||||
static void bta_create_raw_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
|
||||
{
|
||||
tSDP_DISC_ATTR *p_attr;
|
||||
tSDP_PROTOCOL_ELEM pe;
|
||||
|
||||
record->hdr.type = SDP_TYPE_RAW;
|
||||
record->hdr.service_name_length = 0;
|
||||
record->hdr.service_name = NULL;
|
||||
record->hdr.rfcomm_channel_number = -1;
|
||||
record->hdr.l2cap_psm = -1;
|
||||
record->hdr.profile_version = -1;
|
||||
|
||||
/* Try to extract a service name */
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL) {
|
||||
record->pse.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
|
||||
record->pse.hdr.service_name = (char *)p_attr->attr_value.v.array;
|
||||
}
|
||||
|
||||
/* Try to extract an RFCOMM channel */
|
||||
if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
|
||||
record->pse.hdr.rfcomm_channel_number = pe.params[0];
|
||||
}
|
||||
record->hdr.user1_ptr_len = p_bta_sdp_cfg->p_sdp_db->raw_size;
|
||||
record->hdr.user1_ptr = p_bta_sdp_cfg->p_sdp_db->raw_data;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sdp_search_cback
|
||||
**
|
||||
** Description Callback from btm after search is completed
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_sdp_search_cback(UINT16 result, void *user_data)
|
||||
{
|
||||
tSDP_DISC_REC *p_rec = NULL;
|
||||
tBTA_SDP_SEARCH_COMP evt_data = {0}; // We need to zero-initialize
|
||||
tBTA_SDP_STATUS status = BTA_SDP_FAILURE;
|
||||
int count = 0;
|
||||
tBT_UUID su;
|
||||
APPL_TRACE_DEBUG("%s() - res: 0x%x\n", __func__, result);
|
||||
|
||||
bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_NONE;
|
||||
|
||||
if (bta_sdp_cb.p_dm_cback == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
bdcpy(evt_data.remote_addr, bta_sdp_cb.remote_addr);
|
||||
tBT_UUID *uuid = (tBT_UUID *)user_data;
|
||||
memcpy(&evt_data.uuid, uuid, sizeof(tBT_UUID));
|
||||
su = shorten_sdp_uuid(uuid);
|
||||
|
||||
if (result == SDP_SUCCESS || result == SDP_DB_FULL) {
|
||||
do {
|
||||
p_rec = SDP_FindServiceUUIDInDb(p_bta_sdp_cfg->p_sdp_db, &su, p_rec);
|
||||
/* generate the matching record data pointer */
|
||||
if (p_rec != NULL) {
|
||||
status = BTA_SDP_SUCCESS;
|
||||
if (IS_UUID(UUID_MAP_MAS, uuid->uu.uuid128)) {
|
||||
APPL_TRACE_DEBUG("%s() - found MAP (MAS) uuid\n", __func__);
|
||||
bta_create_mas_sdp_record(&evt_data.records[count], p_rec);
|
||||
} else if (IS_UUID(UUID_MAP_MNS, uuid->uu.uuid128)) {
|
||||
APPL_TRACE_DEBUG("%s() - found MAP (MNS) uuid\n", __func__);
|
||||
bta_create_mns_sdp_record(&evt_data.records[count], p_rec);
|
||||
} else if (IS_UUID(UUID_PBAP_PSE, uuid->uu.uuid128)) {
|
||||
APPL_TRACE_DEBUG("%s() - found PBAP (PSE) uuid\n", __func__);
|
||||
bta_create_pse_sdp_record(&evt_data.records[count], p_rec);
|
||||
} else if (IS_UUID(UUID_OBEX_OBJECT_PUSH, uuid->uu.uuid128)) {
|
||||
APPL_TRACE_DEBUG("%s() - found Object Push Server (OPS) uuid\n", __func__);
|
||||
bta_create_ops_sdp_record(&evt_data.records[count], p_rec);
|
||||
} else if (IS_UUID(UUID_SAP, uuid->uu.uuid128)) {
|
||||
APPL_TRACE_DEBUG("%s() - found SAP uuid\n", __func__);
|
||||
bta_create_sap_sdp_record(&evt_data.records[count], p_rec);
|
||||
} else {
|
||||
|
||||
/* we do not have specific structure for this */
|
||||
APPL_TRACE_DEBUG("%s() - profile not identified. using raw data\n", __func__);
|
||||
bta_create_raw_sdp_record(&evt_data.records[count], p_rec);
|
||||
p_rec = NULL; // Terminate loop
|
||||
/* For raw, we only extract the first entry, and then return the entire
|
||||
raw data chunk.
|
||||
TODO: Find a way to split the raw data into record chunks, and iterate
|
||||
to extract generic data for each chunk - e.g. rfcomm channel and
|
||||
service name. */
|
||||
}
|
||||
count++;
|
||||
} else {
|
||||
APPL_TRACE_DEBUG("%s() - UUID not found\n", __func__);
|
||||
}
|
||||
} while (p_rec != NULL && count < BTA_SDP_MAX_RECORDS);
|
||||
|
||||
evt_data.record_count = count;
|
||||
}
|
||||
evt_data.status = status;
|
||||
|
||||
bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, (tBTA_SDP *) &evt_data, (void *)&uuid->uu.uuid128);
|
||||
osi_free(user_data); // We no longer need the user data to track the search
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sdp_enable
|
||||
**
|
||||
** Description Initializes the SDP I/F
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sdp_enable(tBTA_SDP_MSG *p_data)
|
||||
{
|
||||
APPL_TRACE_DEBUG("%s in, sdp_active:%d\n", __func__, bta_sdp_cb.sdp_active);
|
||||
tBTA_SDP_STATUS status = BTA_SDP_SUCCESS;
|
||||
bta_sdp_cb.p_dm_cback = p_data->enable.p_cback;
|
||||
bta_sdp_cb.p_dm_cback(BTA_SDP_ENABLE_EVT, (tBTA_SDP *)&status, NULL);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sdp_search
|
||||
**
|
||||
** Description Discovers all sdp records for an uuid on remote device
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sdp_search(tBTA_SDP_MSG *p_data)
|
||||
{
|
||||
int x = 0;
|
||||
// TODO: Leaks!!! but needed as user-data pointer
|
||||
tBT_UUID *bta_sdp_search_uuid = osi_malloc(sizeof(tBT_UUID));
|
||||
if (p_data == NULL) {
|
||||
APPL_TRACE_DEBUG("SDP control block handle is null\n");
|
||||
return;
|
||||
}
|
||||
tBTA_SDP_STATUS status = BTA_SDP_FAILURE;
|
||||
|
||||
APPL_TRACE_DEBUG("%s in, sdp_active:%d\n", __func__, bta_sdp_cb.sdp_active);
|
||||
|
||||
if (bta_sdp_cb.sdp_active != BTA_SDP_ACTIVE_NONE) {
|
||||
/* SDP is still in progress */
|
||||
status = BTA_SDP_BUSY;
|
||||
if (bta_sdp_cb.p_dm_cback) {
|
||||
tBTA_SDP_SEARCH_COMP result = {0};
|
||||
result.uuid = p_data->get_search.uuid;
|
||||
bdcpy(result.remote_addr, p_data->get_search.bd_addr);
|
||||
result.status = status;
|
||||
bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, (tBTA_SDP *)&result, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_YES;
|
||||
bdcpy(bta_sdp_cb.remote_addr, p_data->get_search.bd_addr);
|
||||
/* set the uuid used in the search */
|
||||
memcpy(bta_sdp_search_uuid, &(p_data->get_search.uuid), sizeof(tBT_UUID));
|
||||
|
||||
/* initialize the search for the uuid */
|
||||
APPL_TRACE_DEBUG("%s init discovery with UUID(len: %d):\n",
|
||||
__func__, bta_sdp_search_uuid->len);
|
||||
for (x = 0; x < bta_sdp_search_uuid->len; x++) {
|
||||
APPL_TRACE_DEBUG("%X", bta_sdp_search_uuid->uu.uuid128[x]);
|
||||
}
|
||||
SDP_InitDiscoveryDb (p_bta_sdp_cfg->p_sdp_db, p_bta_sdp_cfg->sdp_db_size, 1,
|
||||
bta_sdp_search_uuid, 0, NULL);
|
||||
|
||||
if (!SDP_ServiceSearchAttributeRequest2(p_data->get_search.bd_addr, p_bta_sdp_cfg->p_sdp_db,
|
||||
bta_sdp_search_cback, (void *)bta_sdp_search_uuid)) {
|
||||
bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_NONE;
|
||||
|
||||
/* failed to start SDP. report the failure right away */
|
||||
if (bta_sdp_cb.p_dm_cback) {
|
||||
tBTA_SDP_SEARCH_COMP result = {0};
|
||||
result.uuid = p_data->get_search.uuid;
|
||||
bdcpy(result.remote_addr, p_data->get_search.bd_addr);
|
||||
result.status = status;
|
||||
bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, (tBTA_SDP *)&result, NULL);
|
||||
}
|
||||
}
|
||||
/*
|
||||
else report the result when the cback is called
|
||||
*/
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sdp_record
|
||||
**
|
||||
** Description Discovers all sdp records for an uuid on remote device
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sdp_create_record(tBTA_SDP_MSG *p_data)
|
||||
{
|
||||
APPL_TRACE_DEBUG("%s() event: %d\n", __func__, p_data->record.hdr.event);
|
||||
if (bta_sdp_cb.p_dm_cback) {
|
||||
bta_sdp_cb.p_dm_cback(BTA_SDP_CREATE_RECORD_USER_EVT, NULL, p_data->record.user_data);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sdp_create_record
|
||||
**
|
||||
** Description Discovers all sdp records for an uuid on remote device
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sdp_remove_record(tBTA_SDP_MSG *p_data)
|
||||
{
|
||||
APPL_TRACE_DEBUG("%s() event: %d\n", __func__, p_data->record.hdr.event);
|
||||
if (bta_sdp_cb.p_dm_cback) {
|
||||
bta_sdp_cb.p_dm_cback(BTA_SDP_REMOVE_RECORD_USER_EVT, NULL, p_data->record.user_data);
|
||||
}
|
||||
}
|
||||
167
components/bt/bluedroid/bta/sdp/bta_sdp_api.c
Normal file
167
components/bt/bluedroid/bta/sdp/bta_sdp_api.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the implementation of the API for SDP search subsystem
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bta_api.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_sdp_api.h"
|
||||
#include "bta_sdp_int.h"
|
||||
#include "gki.h"
|
||||
#include <string.h>
|
||||
// #include "port_api.h"
|
||||
#include "sdp_api.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
|
||||
static const tBTA_SYS_REG bta_sdp_reg = {
|
||||
bta_sdp_sm_execute,
|
||||
NULL
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_SdpEnable
|
||||
**
|
||||
** Description Enable the SDP search I/F service. When the enable
|
||||
** operation is complete the callback function will be
|
||||
** called with a BTA_SDP_ENABLE_EVT. This function must
|
||||
** be called before other functions in the SDP search API are
|
||||
** called.
|
||||
**
|
||||
** Returns BTA_SDP_SUCCESS if successful.
|
||||
** BTA_SDP_FAIL if internal failure.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_SDP_STATUS BTA_SdpEnable(tBTA_SDP_DM_CBACK *p_cback)
|
||||
{
|
||||
tBTA_SDP_STATUS status = BTA_SDP_FAILURE;
|
||||
tBTA_SDP_API_ENABLE *p_buf;
|
||||
|
||||
APPL_TRACE_API("%s\n", __FUNCTION__);
|
||||
if (p_cback && FALSE == bta_sys_is_register(BTA_ID_SDP)) {
|
||||
memset(&bta_sdp_cb, 0, sizeof(tBTA_SDP_CB));
|
||||
|
||||
/* register with BTA system manager */
|
||||
bta_sys_register(BTA_ID_SDP, &bta_sdp_reg);
|
||||
|
||||
if (p_cback &&
|
||||
(p_buf = (tBTA_SDP_API_ENABLE *) GKI_getbuf(sizeof(tBTA_SDP_API_ENABLE))) != NULL) {
|
||||
p_buf->hdr.event = BTA_SDP_API_ENABLE_EVT;
|
||||
p_buf->p_cback = p_cback;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
status = BTA_SDP_SUCCESS;
|
||||
}
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_SdpSearch
|
||||
**
|
||||
** Description This function performs service discovery for a specific service
|
||||
** on given peer device. When the operation is completed
|
||||
** the tBTA_SDP_DM_CBACK callback function will be called with
|
||||
** a BTA_SDP_SEARCH_COMPLETE_EVT.
|
||||
**
|
||||
** Returns BTA_SDP_SUCCESS, if the request is being processed.
|
||||
** BTA_SDP_FAILURE, otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_SDP_STATUS BTA_SdpSearch(BD_ADDR bd_addr, tSDP_UUID *uuid)
|
||||
{
|
||||
tBTA_SDP_STATUS ret = BTA_SDP_FAILURE;
|
||||
tBTA_SDP_API_SEARCH *p_msg;
|
||||
|
||||
APPL_TRACE_API("%s\n", __FUNCTION__);
|
||||
if ((p_msg = (tBTA_SDP_API_SEARCH *)GKI_getbuf(sizeof(tBTA_SDP_API_SEARCH))) != NULL) {
|
||||
p_msg->hdr.event = BTA_SDP_API_SEARCH_EVT;
|
||||
bdcpy(p_msg->bd_addr, bd_addr);
|
||||
//p_msg->uuid = uuid;
|
||||
memcpy(&(p_msg->uuid), uuid, sizeof(tSDP_UUID));
|
||||
bta_sys_sendmsg(p_msg);
|
||||
ret = BTA_SDP_SUCCESS;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_SdpCreateRecordByUser
|
||||
**
|
||||
** Description This function is used to request a callback to create a SDP
|
||||
** record. The registered callback will be called with event
|
||||
** BTA_SDP_CREATE_RECORD_USER_EVT.
|
||||
**
|
||||
** Returns BTA_SDP_SUCCESS, if the request is being processed.
|
||||
** BTA_SDP_FAILURE, otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_SDP_STATUS BTA_SdpCreateRecordByUser(void *user_data)
|
||||
{
|
||||
tBTA_SDP_STATUS ret = BTA_SDP_FAILURE;
|
||||
tBTA_SDP_API_RECORD_USER *p_msg;
|
||||
|
||||
APPL_TRACE_API("%s\n", __FUNCTION__);
|
||||
if ((p_msg = (tBTA_SDP_API_RECORD_USER *)GKI_getbuf(sizeof(tBTA_SDP_API_RECORD_USER))) != NULL) {
|
||||
p_msg->hdr.event = BTA_SDP_API_CREATE_RECORD_USER_EVT;
|
||||
p_msg->user_data = user_data;
|
||||
bta_sys_sendmsg(p_msg);
|
||||
ret = BTA_SDP_SUCCESS;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_SdpRemoveRecordByUser
|
||||
**
|
||||
** Description This function is used to request a callback to remove a SDP
|
||||
** record. The registered callback will be called with event
|
||||
** BTA_SDP_REMOVE_RECORD_USER_EVT.
|
||||
**
|
||||
** Returns BTA_SDP_SUCCESS, if the request is being processed.
|
||||
** BTA_SDP_FAILURE, otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_SDP_STATUS BTA_SdpRemoveRecordByUser(void *user_data)
|
||||
{
|
||||
tBTA_SDP_STATUS ret = BTA_SDP_FAILURE;
|
||||
tBTA_SDP_API_RECORD_USER *p_msg;
|
||||
|
||||
APPL_TRACE_API("%s\n", __FUNCTION__);
|
||||
if ((p_msg = (tBTA_SDP_API_RECORD_USER *)GKI_getbuf(sizeof(tBTA_SDP_API_RECORD_USER))) != NULL) {
|
||||
p_msg->hdr.event = BTA_SDP_API_REMOVE_RECORD_USER_EVT;
|
||||
p_msg->user_data = user_data;
|
||||
bta_sys_sendmsg(p_msg);
|
||||
ret = BTA_SDP_SUCCESS;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
39
components/bt/bluedroid/bta/sdp/bta_sdp_cfg.c
Normal file
39
components/bt/bluedroid/bta/sdp/bta_sdp_cfg.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
* This file contains compile-time configurable constants for SDP Search
|
||||
******************************************************************************/
|
||||
|
||||
#include "gki.h"
|
||||
#include "bta_api.h"
|
||||
#include "bta_sdp_api.h"
|
||||
|
||||
#ifndef BTA_SDP_DB_SIZE
|
||||
#define BTA_SDP_DB_SIZE 4500
|
||||
#endif
|
||||
|
||||
static UINT8 __attribute__ ((aligned(4))) bta_sdp_db_data[BTA_SDP_DB_SIZE];
|
||||
|
||||
/* SDP configuration structure */
|
||||
const tBTA_SDP_CFG bta_sdp_cfg = {
|
||||
BTA_SDP_DB_SIZE,
|
||||
(tSDP_DISCOVERY_DB *)bta_sdp_db_data /* The data buffer to keep SDP database */
|
||||
};
|
||||
|
||||
tBTA_SDP_CFG *p_bta_sdp_cfg = (tBTA_SDP_CFG *) &bta_sdp_cfg;
|
||||
108
components/bt/bluedroid/bta/sdp/bta_sdp_int.h
Normal file
108
components/bt/bluedroid/bta/sdp/bta_sdp_int.h
Normal file
@@ -0,0 +1,108 @@
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the private interface file for the BTA SDP I/F
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_SDP_INT_H
|
||||
#define BTA_SDP_INT_H
|
||||
|
||||
#include "bta_sys.h"
|
||||
#include "bta_api.h"
|
||||
#include "bta_sdp_api.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
|
||||
enum {
|
||||
/* these events are handled by the state machine */
|
||||
BTA_SDP_API_ENABLE_EVT = BTA_SYS_EVT_START(BTA_ID_SDP),
|
||||
BTA_SDP_API_SEARCH_EVT,
|
||||
BTA_SDP_API_CREATE_RECORD_USER_EVT,
|
||||
BTA_SDP_API_REMOVE_RECORD_USER_EVT,
|
||||
BTA_SDP_MAX_INT_EVT
|
||||
};
|
||||
|
||||
enum {
|
||||
BTA_SDP_ACTIVE_NONE = 0,
|
||||
BTA_SDP_ACTIVE_YES /* waiting for SDP result */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* data type for BTA_SDP_API_ENABLE_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_SDP_DM_CBACK *p_cback;
|
||||
} tBTA_SDP_API_ENABLE;
|
||||
|
||||
/* data type for BTA_SDP_API_SEARCH_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR bd_addr;
|
||||
tSDP_UUID uuid;
|
||||
} tBTA_SDP_API_SEARCH;
|
||||
|
||||
/* data type for BTA_SDP_API_SEARCH_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
void *user_data;
|
||||
} tBTA_SDP_API_RECORD_USER;
|
||||
|
||||
/* union of all data types */
|
||||
typedef union {
|
||||
/* GKI event buffer header */
|
||||
BT_HDR hdr;
|
||||
tBTA_SDP_API_ENABLE enable;
|
||||
tBTA_SDP_API_SEARCH get_search;
|
||||
tBTA_SDP_API_RECORD_USER record;
|
||||
} tBTA_SDP_MSG;
|
||||
|
||||
/* SDP control block */
|
||||
typedef struct {
|
||||
UINT8 sdp_active; /* see BTA_SDP_SDP_ACT_* */
|
||||
BD_ADDR remote_addr;
|
||||
tBTA_SDP_DM_CBACK *p_dm_cback;
|
||||
} tBTA_SDP_CB;
|
||||
|
||||
|
||||
/* SDP control block */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
extern tBTA_SDP_CB bta_sdp_cb;
|
||||
#else
|
||||
extern tBTA_SDP_CB *bta_sdp_cb_ptr;
|
||||
#define bta_sdp_cb (*bta_sdp_cb_ptr)
|
||||
#endif
|
||||
|
||||
/* config struct */
|
||||
extern tBTA_SDP_CFG *p_bta_sdp_cfg;
|
||||
|
||||
extern BOOLEAN bta_sdp_sm_execute(BT_HDR *p_msg);
|
||||
|
||||
extern void bta_sdp_enable (tBTA_SDP_MSG *p_data);
|
||||
extern void bta_sdp_search (tBTA_SDP_MSG *p_data);
|
||||
extern void bta_sdp_create_record(tBTA_SDP_MSG *p_data);
|
||||
extern void bta_sdp_remove_record(tBTA_SDP_MSG *p_data);
|
||||
|
||||
#endif /* BTA_SDP_INT_H */
|
||||
571
components/bt/bluedroid/bta/sys/bta_sys_conn.c
Normal file
571
components/bt/bluedroid/bta/sys/bta_sys_conn.c
Normal file
@@ -0,0 +1,571 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Routes connection status callbacks from various sub systems to DM
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "bta_api.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_sys_int.h"
|
||||
#include "gki.h"
|
||||
#include "utl.h"
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_rm_register
|
||||
**
|
||||
** Description Called by BTA DM to register role management callbacks
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_rm_register(tBTA_SYS_CONN_CBACK *p_cback)
|
||||
{
|
||||
bta_sys_cb.prm_cb = p_cback;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_policy_register
|
||||
**
|
||||
** Description Called by BTA DM to register link policy change callbacks
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_policy_register(tBTA_SYS_CONN_CBACK *p_cback)
|
||||
{
|
||||
bta_sys_cb.p_policy_cb = p_cback;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_role_chg_register
|
||||
**
|
||||
** Description Called by BTA AV to register role change callbacks
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_role_chg_register(tBTA_SYS_CONN_CBACK *p_cback)
|
||||
{
|
||||
bta_sys_cb.p_role_cb = p_cback;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_ssr_cfg_register
|
||||
**
|
||||
** Description Called by BTA DM to register SSR configuration callback
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
void bta_sys_ssr_cfg_register(tBTA_SYS_SSR_CFG_CBACK *p_cback)
|
||||
{
|
||||
bta_sys_cb.p_ssr_cb = p_cback;
|
||||
}
|
||||
#endif
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_role_chg_register
|
||||
**
|
||||
** Description Called by BTA AV to register role change callbacks
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_notify_role_chg(BD_ADDR_PTR p_bda, UINT8 new_role, UINT8 hci_status)
|
||||
{
|
||||
if (bta_sys_cb.p_role_cb) {
|
||||
bta_sys_cb.p_role_cb(BTA_SYS_ROLE_CHANGE, new_role, hci_status, p_bda);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_collision_register
|
||||
**
|
||||
** Description Called by any BTA module to register for collision event.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_collision_register(UINT8 bta_id, tBTA_SYS_CONN_CBACK *p_cback)
|
||||
{
|
||||
UINT8 index;
|
||||
|
||||
for (index = 0; index < MAX_COLLISION_REG; index++) {
|
||||
if ((bta_sys_cb.colli_reg.id[index] == bta_id) ||
|
||||
(bta_sys_cb.colli_reg.id[index] == 0)) {
|
||||
bta_sys_cb.colli_reg.id[index] = bta_id;
|
||||
bta_sys_cb.colli_reg.p_coll_cback[index] = p_cback;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_notify_collision
|
||||
**
|
||||
** Description Called by BTA DM to notify collision event.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_notify_collision (BD_ADDR_PTR p_bda)
|
||||
{
|
||||
UINT8 index;
|
||||
|
||||
for (index = 0; index < MAX_COLLISION_REG; index++) {
|
||||
if ((bta_sys_cb.colli_reg.id[index] != 0) &&
|
||||
(bta_sys_cb.colli_reg.p_coll_cback[index] != NULL)) {
|
||||
bta_sys_cb.colli_reg.p_coll_cback[index] (0, BTA_ID_SYS, 0, p_bda);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_sco_register
|
||||
**
|
||||
** Description Called by BTA AV to register sco connection change callbacks
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_sco_register(tBTA_SYS_CONN_CBACK *p_cback)
|
||||
{
|
||||
bta_sys_cb.p_sco_cb = p_cback;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_pm_register
|
||||
**
|
||||
** Description Called by BTA DM to register power management callbacks
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_pm_register(tBTA_SYS_CONN_CBACK *p_cback)
|
||||
{
|
||||
bta_sys_cb.ppm_cb = p_cback;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_conn_open
|
||||
**
|
||||
** Description Called by BTA subsystems when a connection is made to
|
||||
** the service
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_conn_open(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
if (bta_sys_cb.prm_cb) {
|
||||
|
||||
bta_sys_cb.prm_cb(BTA_SYS_CONN_OPEN, id, app_id, peer_addr);
|
||||
|
||||
}
|
||||
|
||||
if (bta_sys_cb.ppm_cb) {
|
||||
|
||||
bta_sys_cb.ppm_cb(BTA_SYS_CONN_OPEN, id, app_id, peer_addr);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_conn_close
|
||||
**
|
||||
** Description Called by BTA subsystems when a connection to the service
|
||||
** is closed
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_conn_close(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
if (bta_sys_cb.prm_cb) {
|
||||
|
||||
bta_sys_cb.prm_cb(BTA_SYS_CONN_CLOSE, id, app_id, peer_addr);
|
||||
|
||||
}
|
||||
|
||||
if (bta_sys_cb.ppm_cb) {
|
||||
|
||||
bta_sys_cb.ppm_cb(BTA_SYS_CONN_CLOSE, id, app_id, peer_addr);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_app_open
|
||||
**
|
||||
** Description Called by BTA subsystems when application initiates connection
|
||||
** to a peer device
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_app_open(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
if (bta_sys_cb.ppm_cb) {
|
||||
bta_sys_cb.ppm_cb(BTA_SYS_APP_OPEN, id, app_id, peer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_app_close
|
||||
**
|
||||
** Description Called by BTA subsystems when application initiates close
|
||||
** of connection to peer device
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_app_close(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
if (bta_sys_cb.ppm_cb) {
|
||||
bta_sys_cb.ppm_cb(BTA_SYS_APP_CLOSE, id, app_id, peer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_sco_open
|
||||
**
|
||||
** Description Called by BTA subsystems when sco connection for that service
|
||||
** is open
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_sco_open(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
/* AG triggers p_sco_cb by bta_sys_sco_use. */
|
||||
if ((id != BTA_ID_AG) && (bta_sys_cb.p_sco_cb)) {
|
||||
/* without querying BTM_GetNumScoLinks() */
|
||||
bta_sys_cb.p_sco_cb(BTA_SYS_SCO_OPEN, 1, app_id, peer_addr);
|
||||
}
|
||||
|
||||
if (bta_sys_cb.ppm_cb) {
|
||||
bta_sys_cb.ppm_cb(BTA_SYS_SCO_OPEN, id, app_id, peer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_sco_close
|
||||
**
|
||||
** Description Called by BTA subsystems when sco connection for that service
|
||||
** is closed
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_sco_close(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
UINT8 num_sco_links;
|
||||
|
||||
if ((id != BTA_ID_AG) && (bta_sys_cb.p_sco_cb)) {
|
||||
num_sco_links = BTM_GetNumScoLinks();
|
||||
bta_sys_cb.p_sco_cb(BTA_SYS_SCO_CLOSE, num_sco_links, app_id, peer_addr);
|
||||
}
|
||||
|
||||
if (bta_sys_cb.ppm_cb) {
|
||||
bta_sys_cb.ppm_cb(BTA_SYS_SCO_CLOSE, id, app_id, peer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_sco_use
|
||||
**
|
||||
** Description Called by BTA subsystems when that service needs to use sco.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_sco_use(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
UNUSED(id);
|
||||
|
||||
/* AV streaming need to be suspended before SCO is connected. */
|
||||
if (bta_sys_cb.p_sco_cb) {
|
||||
/* without querying BTM_GetNumScoLinks() */
|
||||
bta_sys_cb.p_sco_cb(BTA_SYS_SCO_OPEN, 1, app_id, peer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_sco_unuse
|
||||
**
|
||||
** Description Called by BTA subsystems when sco connection for that service
|
||||
** is no longer needed.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_sco_unuse(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
UINT8 num_sco_links;
|
||||
UNUSED(id);
|
||||
|
||||
if ((bta_sys_cb.p_sco_cb)) {
|
||||
num_sco_links = BTM_GetNumScoLinks();
|
||||
bta_sys_cb.p_sco_cb(BTA_SYS_SCO_CLOSE, num_sco_links, app_id, peer_addr);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_chg_ssr_config
|
||||
**
|
||||
** Description Called by BTA subsystems to indicate that the given app SSR setting
|
||||
** need to be changed.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
void bta_sys_chg_ssr_config (UINT8 id, UINT8 app_id, UINT16 max_latency, UINT16 min_tout)
|
||||
{
|
||||
if (bta_sys_cb.p_ssr_cb) {
|
||||
bta_sys_cb.p_ssr_cb(id, app_id, max_latency, min_tout);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_set_policy
|
||||
**
|
||||
** Description Called by BTA subsystems to indicate that the given link
|
||||
** policy to peer device should be set
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_set_policy (UINT8 id, UINT8 policy, BD_ADDR peer_addr)
|
||||
{
|
||||
if (bta_sys_cb.p_policy_cb) {
|
||||
bta_sys_cb.p_policy_cb(BTA_SYS_PLCY_SET, id, policy, peer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_clear_policy
|
||||
**
|
||||
** Description Called by BTA subsystems to indicate that the given link
|
||||
** policy to peer device should be clear
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_clear_policy (UINT8 id, UINT8 policy, BD_ADDR peer_addr)
|
||||
{
|
||||
if (bta_sys_cb.p_policy_cb) {
|
||||
bta_sys_cb.p_policy_cb(BTA_SYS_PLCY_CLR, id, policy, peer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_set_default_policy
|
||||
**
|
||||
** Description Called by BTA subsystems to indicate that the given default
|
||||
** link policy should be set
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_set_default_policy (UINT8 id, UINT8 policy)
|
||||
{
|
||||
if (bta_sys_cb.p_policy_cb) {
|
||||
bta_sys_cb.p_policy_cb(BTA_SYS_PLCY_DEF_SET, id, policy, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_clear_default_policy
|
||||
**
|
||||
** Description Called by BTA subsystems to indicate that the given default
|
||||
** link policy should be clear
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_clear_default_policy (UINT8 id, UINT8 policy)
|
||||
{
|
||||
if (bta_sys_cb.p_policy_cb) {
|
||||
bta_sys_cb.p_policy_cb(BTA_SYS_PLCY_DEF_CLR, id, policy, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_idle
|
||||
**
|
||||
** Description Called by BTA subsystems to indicate that the connection to
|
||||
** peer device is idle
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_idle(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
|
||||
if (bta_sys_cb.prm_cb) {
|
||||
|
||||
bta_sys_cb.prm_cb(BTA_SYS_CONN_IDLE, id, app_id, peer_addr);
|
||||
|
||||
}
|
||||
|
||||
if (bta_sys_cb.ppm_cb) {
|
||||
|
||||
bta_sys_cb.ppm_cb(BTA_SYS_CONN_IDLE, id, app_id, peer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_busy
|
||||
**
|
||||
** Description Called by BTA subsystems to indicate that the connection to
|
||||
** peer device is busy
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_busy(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
if (bta_sys_cb.prm_cb) {
|
||||
|
||||
bta_sys_cb.prm_cb(BTA_SYS_CONN_BUSY, id, app_id, peer_addr);
|
||||
|
||||
}
|
||||
|
||||
if (bta_sys_cb.ppm_cb) {
|
||||
|
||||
bta_sys_cb.ppm_cb(BTA_SYS_CONN_BUSY, id, app_id, peer_addr);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#if (BTA_EIR_CANNED_UUID_LIST != TRUE)
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_eir_register
|
||||
**
|
||||
** Description Called by BTA DM to register EIR utility function that can be
|
||||
** used by the other BTA modules to add/remove UUID.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_eir_register(tBTA_SYS_EIR_CBACK *p_cback)
|
||||
{
|
||||
bta_sys_cb.eir_cb = p_cback;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_add_uuid
|
||||
**
|
||||
** Description Called by BTA subsystems to indicate to DM that new service
|
||||
** class UUID is added.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_add_uuid(UINT16 uuid16)
|
||||
{
|
||||
if (bta_sys_cb.eir_cb) {
|
||||
bta_sys_cb.eir_cb(uuid16, TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_remove_uuid
|
||||
**
|
||||
** Description Called by BTA subsystems to indicate to DM that the service
|
||||
** class UUID is removed.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_remove_uuid(UINT16 uuid16)
|
||||
{
|
||||
if (bta_sys_cb.eir_cb) {
|
||||
bta_sys_cb.eir_cb(uuid16, FALSE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_vs_hdl
|
||||
**
|
||||
** Description Called by BTA subsystems to execute a VS event handler function
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_sys_vs_hdl(UINT16 evt, void *p)
|
||||
{
|
||||
if (bta_sys_cb.p_vs_evt_hdlr) {
|
||||
return (*bta_sys_cb.p_vs_evt_hdlr)(evt, p);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
729
components/bt/bluedroid/bta/sys/bta_sys_main.c
Normal file
729
components/bt/bluedroid/bta/sys/bta_sys_main.c
Normal file
@@ -0,0 +1,729 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the main implementation file for the BTA system manager.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define LOG_TAG "bt_bta_sys_main"
|
||||
|
||||
// #include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alarm.h"
|
||||
#include "thread.h"
|
||||
#include "btm_api.h"
|
||||
#include "bta_api.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_sys_int.h"
|
||||
|
||||
#include "fixed_queue.h"
|
||||
#include "gki.h"
|
||||
#include "hash_map.h"
|
||||
#include "osi.h"
|
||||
#include "hash_functions.h"
|
||||
// #include "osi/include/log.h"
|
||||
// #include "osi/include/thread.h"
|
||||
#if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
|
||||
#include "bta_ar_api.h"
|
||||
#endif
|
||||
#include "utl.h"
|
||||
|
||||
|
||||
/* system manager control block definition */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
tBTA_SYS_CB bta_sys_cb;
|
||||
#endif
|
||||
|
||||
fixed_queue_t *btu_bta_alarm_queue;
|
||||
static hash_map_t *bta_alarm_hash_map;
|
||||
static const size_t BTA_ALARM_HASH_MAP_SIZE = 17;
|
||||
static pthread_mutex_t bta_alarm_lock;
|
||||
// extern thread_t *bt_workqueue_thread;
|
||||
|
||||
/* trace level */
|
||||
/* TODO Bluedroid - Hard-coded trace levels - Needs to be configurable */
|
||||
UINT8 appl_trace_level = BT_TRACE_LEVEL_WARNING; //APPL_INITIAL_TRACE_LEVEL;
|
||||
UINT8 btif_trace_level = BT_TRACE_LEVEL_WARNING;
|
||||
|
||||
// Communication queue between btu_task and bta.
|
||||
extern fixed_queue_t *btu_bta_msg_queue;
|
||||
void btu_bta_alarm_ready(fixed_queue_t *queue);
|
||||
|
||||
static const tBTA_SYS_REG bta_sys_hw_reg = {
|
||||
bta_sys_sm_execute,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/* type for action functions */
|
||||
typedef void (*tBTA_SYS_ACTION)(tBTA_SYS_HW_MSG *p_data);
|
||||
|
||||
/* action function list */
|
||||
const tBTA_SYS_ACTION bta_sys_action[] = {
|
||||
/* device manager local device API events - cf bta_sys.h for events */
|
||||
bta_sys_hw_api_enable, /* 0 BTA_SYS_HW_API_ENABLE_EVT */
|
||||
bta_sys_hw_evt_enabled, /* 1 BTA_SYS_HW_EVT_ENABLED_EVT */
|
||||
bta_sys_hw_evt_stack_enabled, /* 2 BTA_SYS_HW_EVT_STACK_ENABLED_EVT */
|
||||
bta_sys_hw_api_disable, /* 3 BTA_SYS_HW_API_DISABLE_EVT */
|
||||
bta_sys_hw_evt_disabled, /* 4 BTA_SYS_HW_EVT_DISABLED_EVT */
|
||||
bta_sys_hw_error /* 5 BTA_SYS_HW_ERROR_EVT */
|
||||
};
|
||||
|
||||
/* state machine action enumeration list */
|
||||
enum {
|
||||
/* device manager local device API events */
|
||||
BTA_SYS_HW_API_ENABLE,
|
||||
BTA_SYS_HW_EVT_ENABLED,
|
||||
BTA_SYS_HW_EVT_STACK_ENABLED,
|
||||
BTA_SYS_HW_API_DISABLE,
|
||||
BTA_SYS_HW_EVT_DISABLED,
|
||||
BTA_SYS_HW_ERROR
|
||||
};
|
||||
|
||||
#define BTA_SYS_NUM_ACTIONS (BTA_SYS_MAX_EVT & 0x00ff)
|
||||
#define BTA_SYS_IGNORE BTA_SYS_NUM_ACTIONS
|
||||
|
||||
/* state table information */
|
||||
#define BTA_SYS_ACTIONS 2 /* number of actions */
|
||||
#define BTA_SYS_NEXT_STATE 2 /* position of next state */
|
||||
#define BTA_SYS_NUM_COLS 3 /* number of columns in state tables */
|
||||
|
||||
|
||||
/* state table for OFF state */
|
||||
const UINT8 bta_sys_hw_off[][BTA_SYS_NUM_COLS] = {
|
||||
/* Event Action 1 Action 2 Next State */
|
||||
/* API_ENABLE */ {BTA_SYS_HW_API_ENABLE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING},
|
||||
/* EVT_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING},
|
||||
/* STACK_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
|
||||
/* API_DISABLE */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_IGNORE, BTA_SYS_HW_OFF},
|
||||
/* EVT_DISABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_OFF},
|
||||
/* EVT_ERROR */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_OFF}
|
||||
};
|
||||
|
||||
const UINT8 bta_sys_hw_starting[][BTA_SYS_NUM_COLS] = {
|
||||
/* Event Action 1 Action 2 Next State */
|
||||
/* API_ENABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING}, /* wait for completion event */
|
||||
/* EVT_ENABLED */ {BTA_SYS_HW_EVT_ENABLED, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING},
|
||||
/* STACK_ENABLED */ {BTA_SYS_HW_EVT_STACK_ENABLED, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
|
||||
/* API_DISABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING}, /* successive disable/enable: change state wait for completion to disable */
|
||||
/* EVT_DISABLED */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_HW_API_ENABLE, BTA_SYS_HW_STARTING}, /* successive enable/disable: notify, then restart HW */
|
||||
/* EVT_ERROR */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON}
|
||||
};
|
||||
|
||||
const UINT8 bta_sys_hw_on[][BTA_SYS_NUM_COLS] = {
|
||||
/* Event Action 1 Action 2 Next State */
|
||||
/* API_ENABLE */ {BTA_SYS_HW_API_ENABLE, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
|
||||
/* EVT_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
|
||||
/* STACK_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
|
||||
/* API_DISABLE */ {BTA_SYS_HW_API_DISABLE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, /* don't change the state here, as some other modules might be active */
|
||||
/* EVT_DISABLED */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
|
||||
/* EVT_ERROR */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON}
|
||||
};
|
||||
|
||||
const UINT8 bta_sys_hw_stopping[][BTA_SYS_NUM_COLS] = {
|
||||
/* Event Action 1 Action 2 Next State */
|
||||
/* API_ENABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING}, /* change state, and wait for completion event to enable */
|
||||
/* EVT_ENABLED */ {BTA_SYS_HW_EVT_ENABLED, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING}, /* successive enable/disable: finish the enable before disabling */
|
||||
/* STACK_ENABLED */ {BTA_SYS_HW_EVT_STACK_ENABLED, BTA_SYS_HW_API_DISABLE, BTA_SYS_HW_STOPPING}, /* successive enable/disable: notify, then stop */
|
||||
/* API_DISABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING}, /* wait for completion event */
|
||||
/* EVT_DISABLED */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_IGNORE, BTA_SYS_HW_OFF},
|
||||
/* EVT_ERROR */ {BTA_SYS_HW_API_DISABLE, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING}
|
||||
};
|
||||
|
||||
typedef const UINT8 (*tBTA_SYS_ST_TBL)[BTA_SYS_NUM_COLS];
|
||||
|
||||
/* state table */
|
||||
const tBTA_SYS_ST_TBL bta_sys_st_tbl[] = {
|
||||
bta_sys_hw_off,
|
||||
bta_sys_hw_starting,
|
||||
bta_sys_hw_on,
|
||||
bta_sys_hw_stopping
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_init
|
||||
**
|
||||
** Description BTA initialization; called from task initialization.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_init(void)
|
||||
{
|
||||
memset(&bta_sys_cb, 0, sizeof(tBTA_SYS_CB));
|
||||
|
||||
pthread_mutex_init(&bta_alarm_lock, NULL);
|
||||
|
||||
bta_alarm_hash_map = hash_map_new(BTA_ALARM_HASH_MAP_SIZE,
|
||||
hash_function_pointer, NULL, (data_free_fn)osi_alarm_free, NULL);
|
||||
btu_bta_alarm_queue = fixed_queue_new(SIZE_MAX);
|
||||
|
||||
fixed_queue_register_dequeue(btu_bta_alarm_queue,
|
||||
btu_bta_alarm_ready);
|
||||
|
||||
appl_trace_level = APPL_INITIAL_TRACE_LEVEL;
|
||||
|
||||
/* register BTA SYS message handler */
|
||||
bta_sys_register( BTA_ID_SYS, &bta_sys_hw_reg);
|
||||
|
||||
/* register for BTM notifications */
|
||||
BTM_RegisterForDeviceStatusNotif ((tBTM_DEV_STATUS_CB *)&bta_sys_hw_btm_cback );
|
||||
|
||||
#if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
|
||||
bta_ar_init();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void bta_sys_free(void)
|
||||
{
|
||||
fixed_queue_free(btu_bta_alarm_queue, NULL);
|
||||
hash_map_free(bta_alarm_hash_map);
|
||||
pthread_mutex_destroy(&bta_alarm_lock);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sm_execute
|
||||
**
|
||||
** Description State machine event handling function for DM
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_sys_sm_execute(BT_HDR *p_msg)
|
||||
{
|
||||
BOOLEAN freebuf = TRUE;
|
||||
tBTA_SYS_ST_TBL state_table;
|
||||
UINT8 action;
|
||||
int i;
|
||||
|
||||
APPL_TRACE_EVENT("bta_sys_sm_execute state:%d, event:0x%x\n", bta_sys_cb.state, p_msg->event);
|
||||
|
||||
/* look up the state table for the current state */
|
||||
state_table = bta_sys_st_tbl[bta_sys_cb.state];
|
||||
/* update state */
|
||||
bta_sys_cb.state = state_table[p_msg->event & 0x00ff][BTA_SYS_NEXT_STATE];
|
||||
|
||||
/* execute action functions */
|
||||
for (i = 0; i < BTA_SYS_ACTIONS; i++) {
|
||||
if ((action = state_table[p_msg->event & 0x00ff][i]) != BTA_SYS_IGNORE) {
|
||||
(*bta_sys_action[action])( (tBTA_SYS_HW_MSG *) p_msg);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return freebuf;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void bta_sys_hw_register( tBTA_SYS_HW_MODULE module, tBTA_SYS_HW_CBACK *cback)
|
||||
{
|
||||
bta_sys_cb.sys_hw_cback[module] = cback;
|
||||
}
|
||||
|
||||
|
||||
void bta_sys_hw_unregister( tBTA_SYS_HW_MODULE module )
|
||||
{
|
||||
bta_sys_cb.sys_hw_cback[module] = NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_hw_btm_cback
|
||||
**
|
||||
** Description This function is registered by BTA SYS to BTM in order to get status notifications
|
||||
**
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_hw_btm_cback( tBTM_DEV_STATUS status )
|
||||
{
|
||||
|
||||
tBTA_SYS_HW_MSG *sys_event;
|
||||
|
||||
APPL_TRACE_DEBUG(" bta_sys_hw_btm_cback was called with parameter: %i" , status );
|
||||
|
||||
/* send a message to BTA SYS */
|
||||
if ((sys_event = (tBTA_SYS_HW_MSG *) GKI_getbuf(sizeof(tBTA_SYS_HW_MSG))) != NULL) {
|
||||
if (status == BTM_DEV_STATUS_UP) {
|
||||
sys_event->hdr.event = BTA_SYS_EVT_STACK_ENABLED_EVT;
|
||||
} else if (status == BTM_DEV_STATUS_DOWN) {
|
||||
sys_event->hdr.event = BTA_SYS_ERROR_EVT;
|
||||
} else {
|
||||
/* BTM_DEV_STATUS_CMD_TOUT is ignored for now. */
|
||||
GKI_freebuf (sys_event);
|
||||
sys_event = NULL;
|
||||
}
|
||||
|
||||
if (sys_event) {
|
||||
bta_sys_sendmsg(sys_event);
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_DEBUG("ERROR bta_sys_hw_btm_cback couldn't send msg" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_hw_error
|
||||
**
|
||||
** Description In case the HW device stops answering... Try to turn it off, then re-enable all
|
||||
** previously active SW modules.
|
||||
**
|
||||
** Returns success or failure
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_hw_error(tBTA_SYS_HW_MSG *p_sys_hw_msg)
|
||||
{
|
||||
UINT8 module_index;
|
||||
UNUSED(p_sys_hw_msg);
|
||||
|
||||
APPL_TRACE_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
for (module_index = 0; module_index < BTA_SYS_MAX_HW_MODULES; module_index++) {
|
||||
if ( bta_sys_cb.sys_hw_module_active & ((UINT32)1 << module_index )) {
|
||||
switch ( module_index) {
|
||||
case BTA_SYS_HW_BLUETOOTH:
|
||||
/* Send BTA_SYS_HW_ERROR_EVT to DM */
|
||||
if (bta_sys_cb.sys_hw_cback[module_index] != NULL) {
|
||||
bta_sys_cb.sys_hw_cback[module_index] (BTA_SYS_HW_ERROR_EVT);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* not yet supported */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_hw_enable
|
||||
**
|
||||
** Description this function is called after API enable and HW has been turned on
|
||||
**
|
||||
**
|
||||
** Returns success or failure
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
||||
void bta_sys_hw_api_enable( tBTA_SYS_HW_MSG *p_sys_hw_msg )
|
||||
{
|
||||
if ((!bta_sys_cb.sys_hw_module_active) && (bta_sys_cb.state != BTA_SYS_HW_ON)) {
|
||||
/* register which HW module was turned on */
|
||||
bta_sys_cb.sys_hw_module_active |= ((UINT32)1 << p_sys_hw_msg->hw_module );
|
||||
|
||||
tBTA_SYS_HW_MSG *p_msg;
|
||||
if ((p_msg = (tBTA_SYS_HW_MSG *) GKI_getbuf(sizeof(tBTA_SYS_HW_MSG))) != NULL) {
|
||||
p_msg->hdr.event = BTA_SYS_EVT_ENABLED_EVT;
|
||||
p_msg->hw_module = p_sys_hw_msg->hw_module;
|
||||
|
||||
bta_sys_sendmsg(p_msg);
|
||||
}
|
||||
} else {
|
||||
/* register which HW module was turned on */
|
||||
bta_sys_cb.sys_hw_module_active |= ((UINT32)1 << p_sys_hw_msg->hw_module );
|
||||
|
||||
/* HW already in use, so directly notify the caller */
|
||||
if (bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ] != NULL ) {
|
||||
bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ]( BTA_SYS_HW_ON_EVT );
|
||||
}
|
||||
}
|
||||
|
||||
APPL_TRACE_EVENT ("bta_sys_hw_api_enable for %d, active modules 0x%04X\n",
|
||||
p_sys_hw_msg->hw_module, bta_sys_cb.sys_hw_module_active);
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_hw_disable
|
||||
**
|
||||
** Description if no other module is using the HW, this function will call ( if defined ) a user-macro to turn off the HW
|
||||
**
|
||||
**
|
||||
** Returns success or failure
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_hw_api_disable(tBTA_SYS_HW_MSG *p_sys_hw_msg)
|
||||
{
|
||||
APPL_TRACE_DEBUG("bta_sys_hw_api_disable for %d, active modules: 0x%04X\n",
|
||||
p_sys_hw_msg->hw_module, bta_sys_cb.sys_hw_module_active );
|
||||
|
||||
/* make sure the related SW blocks were stopped */
|
||||
bta_sys_disable( p_sys_hw_msg->hw_module );
|
||||
|
||||
|
||||
/* register which module we turn off */
|
||||
bta_sys_cb.sys_hw_module_active &= ~((UINT32)1 << p_sys_hw_msg->hw_module );
|
||||
|
||||
|
||||
/* if there are still some SW modules using the HW, just provide an answer to the calling */
|
||||
if ( bta_sys_cb.sys_hw_module_active != 0 ) {
|
||||
/* if there are still some SW modules using the HW, directly notify the caller */
|
||||
if ( bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ] != NULL ) {
|
||||
bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ]( BTA_SYS_HW_OFF_EVT );
|
||||
}
|
||||
} else {
|
||||
/* manually update the state of our system */
|
||||
bta_sys_cb.state = BTA_SYS_HW_STOPPING;
|
||||
|
||||
tBTA_SYS_HW_MSG *p_msg;
|
||||
if ((p_msg = (tBTA_SYS_HW_MSG *) GKI_getbuf(sizeof(tBTA_SYS_HW_MSG))) != NULL) {
|
||||
p_msg->hdr.event = BTA_SYS_EVT_DISABLED_EVT;
|
||||
p_msg->hw_module = p_sys_hw_msg->hw_module;
|
||||
|
||||
bta_sys_sendmsg(p_msg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_hw_event_enabled
|
||||
**
|
||||
** Description
|
||||
**
|
||||
**
|
||||
** Returns success or failure
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_hw_evt_enabled(tBTA_SYS_HW_MSG *p_sys_hw_msg)
|
||||
{
|
||||
APPL_TRACE_EVENT("bta_sys_hw_evt_enabled for %i\n", p_sys_hw_msg->hw_module);
|
||||
BTM_DeviceReset( NULL );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_hw_event_disabled
|
||||
**
|
||||
** Description
|
||||
**
|
||||
**
|
||||
** Returns success or failure
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_hw_evt_disabled(tBTA_SYS_HW_MSG *p_sys_hw_msg)
|
||||
{
|
||||
UINT8 hw_module_index;
|
||||
|
||||
APPL_TRACE_DEBUG("bta_sys_hw_evt_disabled - module 0x%X\n", p_sys_hw_msg->hw_module);
|
||||
|
||||
for (hw_module_index = 0; hw_module_index < BTA_SYS_MAX_HW_MODULES; hw_module_index++) {
|
||||
if (bta_sys_cb.sys_hw_cback[hw_module_index] != NULL) {
|
||||
bta_sys_cb.sys_hw_cback[hw_module_index] (BTA_SYS_HW_OFF_EVT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_hw_event_stack_enabled
|
||||
**
|
||||
** Description we receive this event once the SW side is ready ( stack, FW download,... ),
|
||||
** i.e. we can really start using the device. So notify the app.
|
||||
**
|
||||
** Returns success or failure
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_hw_evt_stack_enabled(tBTA_SYS_HW_MSG *p_sys_hw_msg)
|
||||
{
|
||||
UINT8 hw_module_index;
|
||||
UNUSED(p_sys_hw_msg);
|
||||
|
||||
APPL_TRACE_DEBUG(" bta_sys_hw_evt_stack_enabled!notify the callers\n");
|
||||
|
||||
for (hw_module_index = 0; hw_module_index < BTA_SYS_MAX_HW_MODULES; hw_module_index++ ) {
|
||||
if (bta_sys_cb.sys_hw_cback[hw_module_index] != NULL) {
|
||||
bta_sys_cb.sys_hw_cback[hw_module_index] (BTA_SYS_HW_ON_EVT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_event
|
||||
**
|
||||
** Description BTA event handler; called from task event handler.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_event(BT_HDR *p_msg)
|
||||
{
|
||||
UINT8 id;
|
||||
BOOLEAN freebuf = TRUE;
|
||||
|
||||
APPL_TRACE_EVENT("BTA got event 0x%x\n", p_msg->event);
|
||||
|
||||
/* get subsystem id from event */
|
||||
id = (UINT8) (p_msg->event >> 8);
|
||||
|
||||
/* verify id and call subsystem event handler */
|
||||
if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL)) {
|
||||
freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
|
||||
} else {
|
||||
APPL_TRACE_WARNING("BTA got unregistered event id %d\n", id);
|
||||
}
|
||||
|
||||
if (freebuf) {
|
||||
GKI_freebuf(p_msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_register
|
||||
**
|
||||
** Description Called by other BTA subsystems to register their event
|
||||
** handler.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_register(UINT8 id, const tBTA_SYS_REG *p_reg)
|
||||
{
|
||||
bta_sys_cb.reg[id] = (tBTA_SYS_REG *) p_reg;
|
||||
bta_sys_cb.is_reg[id] = TRUE;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_deregister
|
||||
**
|
||||
** Description Called by other BTA subsystems to de-register
|
||||
** handler.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_deregister(UINT8 id)
|
||||
{
|
||||
bta_sys_cb.is_reg[id] = FALSE;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_is_register
|
||||
**
|
||||
** Description Called by other BTA subsystems to get registeration
|
||||
** status.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_sys_is_register(UINT8 id)
|
||||
{
|
||||
return bta_sys_cb.is_reg[id];
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_sendmsg
|
||||
**
|
||||
** Description Send a GKI message to BTA. This function is designed to
|
||||
** optimize sending of messages to BTA. It is called by BTA
|
||||
** API functions and call-in functions.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_sendmsg(void *p_msg)
|
||||
{
|
||||
// There is a race condition that occurs if the stack is shut down while
|
||||
// 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.
|
||||
if (btu_bta_msg_queue) {
|
||||
fixed_queue_enqueue(btu_bta_msg_queue, p_msg);
|
||||
//ke_event_set(KE_EVENT_BTU_TASK_THREAD);
|
||||
btu_task_post(SIG_BTU_WORK);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_start_timer
|
||||
**
|
||||
** Description Start a protocol timer for the specified amount
|
||||
** of time in milliseconds.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_alarm_cb(void *data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
|
||||
|
||||
fixed_queue_enqueue(btu_bta_alarm_queue, p_tle);
|
||||
|
||||
btu_task_post(SIG_BTU_WORK);
|
||||
}
|
||||
|
||||
void bta_sys_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout_ms)
|
||||
{
|
||||
assert(p_tle != NULL);
|
||||
|
||||
// Get the alarm for this p_tle.
|
||||
pthread_mutex_lock(&bta_alarm_lock);
|
||||
if (!hash_map_has_key(bta_alarm_hash_map, p_tle)) {
|
||||
hash_map_set(bta_alarm_hash_map, p_tle, osi_alarm_new("bta_sys", bta_alarm_cb, p_tle, 0));
|
||||
}
|
||||
pthread_mutex_unlock(&bta_alarm_lock);
|
||||
|
||||
osi_alarm_t *alarm = hash_map_get(bta_alarm_hash_map, p_tle);
|
||||
if (alarm == NULL) {
|
||||
LOG_ERROR("%s unable to create alarm.", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
p_tle->event = type;
|
||||
p_tle->ticks = timeout_ms;
|
||||
//osi_alarm_set(alarm, (period_ms_t)timeout_ms, bta_alarm_cb, p_tle);
|
||||
osi_alarm_set(alarm, (period_ms_t)timeout_ms);
|
||||
}
|
||||
|
||||
bool hash_iter_ro_cb(hash_map_entry_t *hash_map_entry, void *context)
|
||||
{
|
||||
osi_alarm_t *alarm = (osi_alarm_t *)hash_map_entry->data;
|
||||
period_ms_t *p_remaining_ms = (period_ms_t *)context;
|
||||
*p_remaining_ms += osi_alarm_get_remaining_ms(alarm);
|
||||
return true;
|
||||
}
|
||||
|
||||
UINT32 bta_sys_get_remaining_ticks(TIMER_LIST_ENT *p_target_tle)
|
||||
{
|
||||
period_ms_t remaining_ms = 0;
|
||||
pthread_mutex_lock(&bta_alarm_lock);
|
||||
// Get the alarm for this p_tle
|
||||
hash_map_foreach(bta_alarm_hash_map, hash_iter_ro_cb, &remaining_ms);
|
||||
pthread_mutex_unlock(&bta_alarm_lock);
|
||||
return remaining_ms;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_stop_timer
|
||||
**
|
||||
** Description Stop a BTA timer.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_stop_timer(TIMER_LIST_ENT *p_tle)
|
||||
{
|
||||
assert(p_tle != NULL);
|
||||
|
||||
osi_alarm_t *alarm = hash_map_get(bta_alarm_hash_map, p_tle);
|
||||
if (alarm == NULL) {
|
||||
LOG_DEBUG("%s expected alarm was not in bta alarm hash map.", __func__);
|
||||
return;
|
||||
}
|
||||
osi_alarm_cancel(alarm);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_disable
|
||||
**
|
||||
** Description For each registered subsystem execute its disable function.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_disable(tBTA_SYS_HW_MODULE module)
|
||||
{
|
||||
int bta_id = 0;
|
||||
int bta_id_max = 0;
|
||||
|
||||
APPL_TRACE_DEBUG("bta_sys_disable: module %i", module);
|
||||
|
||||
switch ( module ) {
|
||||
case BTA_SYS_HW_BLUETOOTH:
|
||||
bta_id = BTA_ID_DM;
|
||||
bta_id_max = BTA_ID_BLUETOOTH_MAX;
|
||||
break;
|
||||
default:
|
||||
APPL_TRACE_WARNING("bta_sys_disable: unkown module");
|
||||
return;
|
||||
}
|
||||
|
||||
for ( ; bta_id <= bta_id_max; bta_id++) {
|
||||
if (bta_sys_cb.reg[bta_id] != NULL) {
|
||||
if (bta_sys_cb.is_reg[bta_id] == TRUE && bta_sys_cb.reg[bta_id]->disable != NULL) {
|
||||
(*bta_sys_cb.reg[bta_id]->disable)();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_set_trace_level
|
||||
**
|
||||
** Description Set trace level for BTA
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_set_trace_level(UINT8 level)
|
||||
{
|
||||
appl_trace_level = level;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_get_sys_features
|
||||
**
|
||||
** Description Returns sys_features to other BTA modules.
|
||||
**
|
||||
** Returns sys_features
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT16 bta_sys_get_sys_features (void)
|
||||
{
|
||||
return bta_sys_cb.sys_features;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user