forked from espressif/esp-idf
Compare commits
2518 Commits
v0.9
...
release/v2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c70a613127 | ||
|
|
c5498468d8 | ||
|
|
7c74ed8638 | ||
|
|
6e9b9c95df | ||
|
|
2fa801dec4 | ||
|
|
df3ef3184a | ||
|
|
ca9993eca3 | ||
|
|
ef7ce1069f | ||
|
|
3baa4e39b3 | ||
|
|
137d407e66 | ||
|
|
2b089968fe | ||
|
|
e5066ed5cb | ||
|
|
dcf1db17f7 | ||
|
|
43a04ebcf1 | ||
|
|
8bca703467 | ||
|
|
0f9925cfc8 | ||
|
|
c092079587 | ||
|
|
bb309f0acf | ||
|
|
ebc8877b75 | ||
|
|
11613ba7a7 | ||
|
|
5af843f61b | ||
|
|
a237327eff | ||
|
|
4f603017bd | ||
|
|
e324707cc8 | ||
|
|
07543dfec4 | ||
|
|
d262fe4bc9 | ||
|
|
fd20a89e20 | ||
|
|
d6b8602892 | ||
|
|
dfb1c41a28 | ||
|
|
378f3463fe | ||
|
|
0c67282bc5 | ||
|
|
305e2695d6 | ||
|
|
f108f5394f | ||
|
|
3aad5a09f4 | ||
|
|
6d16de8999 | ||
|
|
4aa6551fe0 | ||
|
|
e2e46f4243 | ||
|
|
c8525c21b9 | ||
|
|
0e290863db | ||
|
|
e5b75b4a17 | ||
|
|
207524f3da | ||
|
|
e5d5727969 | ||
|
|
3a9781ff45 | ||
|
|
edbd744991 | ||
|
|
817d75a4e1 | ||
|
|
a73c78a85b | ||
|
|
84413f641d | ||
|
|
b6c91ce088 | ||
|
|
0c75b6e6e6 | ||
|
|
90aafbd25b | ||
|
|
b95a6b01ba | ||
|
|
151c6d9016 | ||
|
|
62c2c37606 | ||
|
|
3eeaae0573 | ||
|
|
43b25e2a2f | ||
|
|
74879c66e0 | ||
|
|
5db3b86871 | ||
|
|
65734a8344 | ||
|
|
fdb390aeac | ||
|
|
f285d8f678 | ||
|
|
6f7d6dbde4 | ||
|
|
348825a438 | ||
|
|
23d7dd8b8e | ||
|
|
301fcad36b | ||
|
|
7655f3e92c | ||
|
|
a61ef26be1 | ||
|
|
0f238dcdec | ||
|
|
70f3dccaf5 | ||
|
|
8e3de3fbde | ||
|
|
691c8693e6 | ||
|
|
25b0a4f514 | ||
|
|
fbdec19c23 | ||
|
|
4fd437d466 | ||
|
|
00b5f82c41 | ||
|
|
3062790128 | ||
|
|
024f853964 | ||
|
|
cf185846f5 | ||
|
|
7138fb0290 | ||
|
|
b7f7a92c5d | ||
|
|
27574a31e7 | ||
|
|
8134140acd | ||
|
|
efdbc63b5f | ||
|
|
1891382db6 | ||
|
|
16cd517410 | ||
|
|
8fc78a958a | ||
|
|
3cbaf98d29 | ||
|
|
b2d41a3506 | ||
|
|
5d1ec0da02 | ||
|
|
6a9e9759ea | ||
|
|
0de622e4f6 | ||
|
|
fc67a8b1b9 | ||
|
|
41f43164e2 | ||
|
|
2236ab7bd4 | ||
|
|
a281359db0 | ||
|
|
1fb777cc49 | ||
|
|
92facb6884 | ||
|
|
eb38883217 | ||
|
|
5d736f7eca | ||
|
|
bdc499aea7 | ||
|
|
99dbfb3539 | ||
|
|
8d3e1a2a79 | ||
|
|
f33b0fd4c9 | ||
|
|
b99551b48f | ||
|
|
6c04e3ee6a | ||
|
|
6878c4e329 | ||
|
|
f54a656932 | ||
|
|
305564cd59 | ||
|
|
6bceb41bf7 | ||
|
|
2e9db99921 | ||
|
|
fa7d3f38fc | ||
|
|
602e223c9c | ||
|
|
baa743c7b9 | ||
|
|
6db29f0766 | ||
|
|
abec2392c7 | ||
|
|
8a54ebe02e | ||
|
|
0a1c68d7b6 | ||
|
|
494641c481 | ||
|
|
3ab2436b11 | ||
|
|
ee86c15ab8 | ||
|
|
9deaa6ab60 | ||
|
|
8a5c1e9209 | ||
|
|
3d3994632b | ||
|
|
17dd3e9ca0 | ||
|
|
c40bbc5c42 | ||
|
|
1b3120615b | ||
|
|
3365b9322b | ||
|
|
852e94d73a | ||
|
|
09bb7a7650 | ||
|
|
4f4fb7b453 | ||
|
|
663129abce | ||
|
|
9cf81f754b | ||
|
|
3bd3640d60 | ||
|
|
1480251aa7 | ||
|
|
24c4bc9cc4 | ||
|
|
a225064bfa | ||
|
|
85baf0afaa | ||
|
|
e918ee20da | ||
|
|
dc0632789f | ||
|
|
3dd2861e2a | ||
|
|
df76a904b0 | ||
|
|
425215e28e | ||
|
|
d79aeab3aa | ||
|
|
8411aa7362 | ||
|
|
55c0a4ea60 | ||
|
|
45037efc45 | ||
|
|
b772024699 | ||
|
|
157749c77b | ||
|
|
8eeaef6eb6 | ||
|
|
21f02a6955 | ||
|
|
bbf449dbde | ||
|
|
328e93ddc4 | ||
|
|
5b678eed0d | ||
|
|
1015780931 | ||
|
|
4f71b4574a | ||
|
|
eec989f026 | ||
|
|
2ccfe3da96 | ||
|
|
7ed8c66547 | ||
|
|
89d503edf0 | ||
|
|
bf5ff89291 | ||
|
|
9edf376bc3 | ||
|
|
05f56d1d25 | ||
|
|
554b77bd56 | ||
|
|
59479eb7dd | ||
|
|
cc93e14770 | ||
|
|
01705166bc | ||
|
|
14125f3361 | ||
|
|
e334b7267e | ||
|
|
3f8e58a637 | ||
|
|
4d4b0b646d | ||
|
|
c4edb2a439 | ||
|
|
055c7420fd | ||
|
|
d2bada24dc | ||
|
|
99962b7905 | ||
|
|
c8201275f7 | ||
|
|
1c798b0eab | ||
|
|
0d318ea2da | ||
|
|
a5c5748de2 | ||
|
|
07ccbb8dbc | ||
|
|
ff6c0a6cc8 | ||
|
|
7c50916c53 | ||
|
|
769944b067 | ||
|
|
f50b5481fa | ||
|
|
e045253883 | ||
|
|
bb4a87dbfe | ||
|
|
8ccb2a4990 | ||
|
|
9a6b1c3b11 | ||
|
|
1739216787 | ||
|
|
a64f5de091 | ||
|
|
1cae2da0a0 | ||
|
|
fe1f8a25b5 | ||
|
|
85e9a0fa17 | ||
|
|
fd12a6c706 | ||
|
|
09f7cf45dd | ||
|
|
ffdcbc5355 | ||
|
|
8cb0d52c43 | ||
|
|
6538ebe8ad | ||
|
|
b78a8ae035 | ||
|
|
9353666cc1 | ||
|
|
a72b1abc51 | ||
|
|
75658ee29b | ||
|
|
58b65291d9 | ||
|
|
f114ef4a6a | ||
|
|
491932b80c | ||
|
|
ac5040a7c2 | ||
|
|
643a79c527 | ||
|
|
83b7144207 | ||
|
|
5f24dcdf4e | ||
|
|
6ffa30a408 | ||
|
|
113c21a481 | ||
|
|
2e33dace16 | ||
|
|
7cf5eea36f | ||
|
|
a18032fe80 | ||
|
|
e2e5f4caae | ||
|
|
435b907475 | ||
|
|
a03e5f95be | ||
|
|
00bcee2df2 | ||
|
|
aefde1517d | ||
|
|
60d5b677e7 | ||
|
|
ae7269d39d | ||
|
|
6b3a559ee7 | ||
|
|
55bec0e82f | ||
|
|
db87a640ea | ||
|
|
211580bf4f | ||
|
|
8e0ec6a9ab | ||
|
|
6068c1be9a | ||
|
|
c5debed621 | ||
|
|
06fa08b022 | ||
|
|
28e84a5299 | ||
|
|
69e8085624 | ||
|
|
243bc97119 | ||
|
|
3f997d3e8c | ||
|
|
643aa41953 | ||
|
|
0c83e46b08 | ||
|
|
6e704fc421 | ||
|
|
af1bec4625 | ||
|
|
71d7716a45 | ||
|
|
91593a5237 | ||
|
|
8bf675786a | ||
|
|
5d7bffea2b | ||
|
|
3d963f1c61 | ||
|
|
81f98c0a77 | ||
|
|
ff8287645b | ||
|
|
12c1238730 | ||
|
|
2a759a9864 | ||
|
|
063dccd6c0 | ||
|
|
bf4dd5175b | ||
|
|
1ce18758d4 | ||
|
|
57d27faee8 | ||
|
|
cd89a653e4 | ||
|
|
be680a0ef3 | ||
|
|
808b07799c | ||
|
|
96f8e0d996 | ||
|
|
47e789f538 | ||
|
|
cc8af68244 | ||
|
|
f327a9b1cf | ||
|
|
352cc0c7fe | ||
|
|
a8075df8dc | ||
|
|
b8782bdd90 | ||
|
|
411b5ecc43 | ||
|
|
e07482504a | ||
|
|
4734ba40b0 | ||
|
|
11d2db40f4 | ||
|
|
edd2459934 | ||
|
|
e5adfb8119 | ||
|
|
c5b5dd88f9 | ||
|
|
c77b699463 | ||
|
|
a7dde817f9 | ||
|
|
450b9a4e5c | ||
|
|
6606c51728 | ||
|
|
5f49b04428 | ||
|
|
e7db29b2a8 | ||
|
|
5a1a8b4637 | ||
|
|
c1e8988240 | ||
|
|
4b58cc12cd | ||
|
|
a89e93fc3d | ||
|
|
30783d481d | ||
|
|
058eb26574 | ||
|
|
bd309731da | ||
|
|
99d5959d8a | ||
|
|
35f6a2a8af | ||
|
|
460c37ddf6 | ||
|
|
7da4b42ed1 | ||
|
|
82b8b1db1f | ||
|
|
b78242da58 | ||
|
|
b2b9dd6302 | ||
|
|
f40be8eb77 | ||
|
|
e6acc32df6 | ||
|
|
531f751fd3 | ||
|
|
db96edc5d9 | ||
|
|
1cbdb35e1e | ||
|
|
99454d4a73 | ||
|
|
ae05787a51 | ||
|
|
d00b2428bb | ||
|
|
b0d93fccce | ||
|
|
7ea33771c7 | ||
|
|
bb6189b335 | ||
|
|
ca4506fba9 | ||
|
|
ba32dd30a1 | ||
|
|
d4b0f85eb4 | ||
|
|
b9fc5ecf68 | ||
|
|
f40ae10a5d | ||
|
|
35dae5dff5 | ||
|
|
764a70752a | ||
|
|
17da994345 | ||
|
|
91718cc776 | ||
|
|
2e7f6a2247 | ||
|
|
e45a288516 | ||
|
|
a42bf640bc | ||
|
|
592b8a4325 | ||
|
|
9b39be9559 | ||
|
|
cc46038142 | ||
|
|
bd17791fd4 | ||
|
|
0a66f0db4c | ||
|
|
cd58f089c2 | ||
|
|
1eaf88262d | ||
|
|
be3eda0044 | ||
|
|
77a53e528a | ||
|
|
66ef886d77 | ||
|
|
ab0f7264ee | ||
|
|
f5a59f4f78 | ||
|
|
6873c19131 | ||
|
|
144d345b3b | ||
|
|
b428d28950 | ||
|
|
5389329729 | ||
|
|
d2f24f1b81 | ||
|
|
fc130fba86 | ||
|
|
3a787c4830 | ||
|
|
7abd9bc023 | ||
|
|
06accaf851 | ||
|
|
d1fb51afd2 | ||
|
|
a25a4a0a7c | ||
|
|
3b5cb5ad67 | ||
|
|
4947c953d3 | ||
|
|
d718cbd873 | ||
|
|
034d37b9cb | ||
|
|
2b1365a51b | ||
|
|
636d2b384e | ||
|
|
28cec08450 | ||
|
|
e9fae704e3 | ||
|
|
9679c238aa | ||
|
|
826e96248d | ||
|
|
87a5bd0179 | ||
|
|
adac20dc36 | ||
|
|
e40810adbb | ||
|
|
81ff34742b | ||
|
|
e0ac345fd2 | ||
|
|
2427809c9d | ||
|
|
0c6d966bff | ||
|
|
79ca00af49 | ||
|
|
baf446e871 | ||
|
|
66bb6a2f2b | ||
|
|
d12f871be6 | ||
|
|
37af544c9a | ||
|
|
e30459b0de | ||
|
|
2aadbee43c | ||
|
|
3c583a7655 | ||
|
|
9634f1815d | ||
|
|
cdea87168c | ||
|
|
c0fa8a0354 | ||
|
|
2567696cc3 | ||
|
|
f68c5baea6 | ||
|
|
ba55461686 | ||
|
|
5c9bb591d3 | ||
|
|
365b66b95b | ||
|
|
55fb4c54c8 | ||
|
|
5413a115b7 | ||
|
|
4ffb4911e1 | ||
|
|
215ada6479 | ||
|
|
99771a255f | ||
|
|
30edcca1fb | ||
|
|
a38cecefa7 | ||
|
|
b763bb7c50 | ||
|
|
25b07ed79a | ||
|
|
8ae0eb059e | ||
|
|
fded7b4270 | ||
|
|
972d1d9242 | ||
|
|
67a147fc6f | ||
|
|
45c815f9ad | ||
|
|
dbb862299d | ||
|
|
df3164bd58 | ||
|
|
356ce2f15a | ||
|
|
da5d166356 | ||
|
|
d8c0b505f6 | ||
|
|
b5e2bcbb2c | ||
|
|
0d66ac256b | ||
|
|
46519a019c | ||
|
|
9229902dff | ||
|
|
b401bbc4d6 | ||
|
|
8f1a6989ee | ||
|
|
b95bef4d9b | ||
|
|
d13c083397 | ||
|
|
b6063d160c | ||
|
|
52515d0edf | ||
|
|
1ddf40feb7 | ||
|
|
3ac3a78d7d | ||
|
|
0b447db8d8 | ||
|
|
66191fc0b5 | ||
|
|
31de20a217 | ||
|
|
a40fd2e7bd | ||
|
|
3d6da958d3 | ||
|
|
00cdf62ce7 | ||
|
|
f59bf74057 | ||
|
|
e797cd03f0 | ||
|
|
4dad7ab621 | ||
|
|
19aa2493c4 | ||
|
|
98e15df7f6 | ||
|
|
3d22f1ee2f | ||
|
|
1e0710f1b2 | ||
|
|
a6608648db | ||
|
|
9e46b89a75 | ||
|
|
bb25ac91f4 | ||
|
|
23965694b1 | ||
|
|
1f055d28b8 | ||
|
|
2008f4d88c | ||
|
|
377a1f5ea1 | ||
|
|
9a64744850 | ||
|
|
272551301e | ||
|
|
b576893167 | ||
|
|
e9dc0115fc | ||
|
|
51f20c6e7c | ||
|
|
00e02b9997 | ||
|
|
bf01525fc1 | ||
|
|
7eb0b3c2d7 | ||
|
|
c9969ab996 | ||
|
|
aaa8170865 | ||
|
|
beffcd6468 | ||
|
|
dc78c55f61 | ||
|
|
15a6145961 | ||
|
|
67b08c20ec | ||
|
|
c742f7d860 | ||
|
|
4235b4c13e | ||
|
|
304f0a399a | ||
|
|
3f68c5e988 | ||
|
|
895e7423a3 | ||
|
|
ca4f5b9ee6 | ||
|
|
c518325385 | ||
|
|
b22067a8f0 | ||
|
|
eb00de5384 | ||
|
|
26a3cb93c7 | ||
|
|
84aeb2823a | ||
|
|
f7e8856520 | ||
|
|
a41ac2d21d | ||
|
|
9962cc9c9f | ||
|
|
04eb6f6129 | ||
|
|
8e3c30a27d | ||
|
|
da67773b02 | ||
|
|
5d4783ee07 | ||
|
|
b045df6507 | ||
|
|
659cd2af43 | ||
|
|
24862b1a6c | ||
|
|
65acd99cce | ||
|
|
71401bc9b3 | ||
|
|
fd079a8bd6 | ||
|
|
db295b24f9 | ||
|
|
2260c714e7 | ||
|
|
33b8b7855e | ||
|
|
00358beb98 | ||
|
|
0a56b748df | ||
|
|
3453824bf2 | ||
|
|
a7847dbec9 | ||
|
|
4223c795a7 | ||
|
|
195358ddb7 | ||
|
|
f9e3900fb2 | ||
|
|
7347b7daa6 | ||
|
|
9f0dae4aeb | ||
|
|
53d5c5f668 | ||
|
|
5ac28e843d | ||
|
|
4e3ea66ec4 | ||
|
|
a428af8c9f | ||
|
|
d18157e108 | ||
|
|
1a73b41b10 | ||
|
|
72c7941b5e | ||
|
|
8af3fe4e84 | ||
|
|
530c3ca05c | ||
|
|
dfb8aa6257 | ||
|
|
fb45ee7a4c | ||
|
|
b65779eefe | ||
|
|
7308db6f94 | ||
|
|
244fbf1e84 | ||
|
|
8f9707fd07 | ||
|
|
79d9d35414 | ||
|
|
4a09d6b062 | ||
|
|
d648835def | ||
|
|
c0825b35c1 | ||
|
|
33632aa29f | ||
|
|
1cef8d8ac1 | ||
|
|
29d620fa10 | ||
|
|
6c5e60943e | ||
|
|
2b273388dd | ||
|
|
07b61d54f7 | ||
|
|
e18f8da528 | ||
|
|
d7faf52a9b | ||
|
|
4c01929a1e | ||
|
|
e8a3f87e4f | ||
|
|
834d980e39 | ||
|
|
e86b2dc9c3 | ||
|
|
5c0d0d4854 | ||
|
|
523a76fe0b | ||
|
|
5cf3b1c201 | ||
|
|
7db85a386a | ||
|
|
22a12e3768 | ||
|
|
1a19747678 | ||
|
|
6f0a9f76cd | ||
|
|
b8c1720736 | ||
|
|
5728c8bd2a | ||
|
|
0759897bfb | ||
|
|
a21d524ca0 | ||
|
|
899a5d223f | ||
|
|
aeecbcc7ee | ||
|
|
9134c13c73 | ||
|
|
100d2dd938 | ||
|
|
1c3b40adeb | ||
|
|
46fa2cfb46 | ||
|
|
04b901e629 | ||
|
|
bf0c32364a | ||
|
|
881a90b8ab | ||
|
|
cecb846450 | ||
|
|
4c06dca15c | ||
|
|
e9c372bc2d | ||
|
|
69bf14360d | ||
|
|
a2332bc18f | ||
|
|
3531af91a1 | ||
|
|
2ad9cd36e2 | ||
|
|
04bd221867 | ||
|
|
fc1ee2666a | ||
|
|
14859cb0fe | ||
|
|
079b0128de | ||
|
|
1324e565fa | ||
|
|
fe695a9af8 | ||
|
|
98895af68b | ||
|
|
54aaeacb32 | ||
|
|
c31953a005 | ||
|
|
a3717515a2 | ||
|
|
baeab37560 | ||
|
|
891257b4dd | ||
|
|
0fe765a977 | ||
|
|
00aa73c6cf | ||
|
|
6353bc40d7 | ||
|
|
d5a63fe042 | ||
|
|
32fc0a62b9 | ||
|
|
66726ec166 | ||
|
|
572e320795 | ||
|
|
08cfcbb6ea | ||
|
|
e2479b46f7 | ||
|
|
a4d9aadeca | ||
|
|
09f69fe9ea | ||
|
|
b540322dc1 | ||
|
|
16cdd86579 | ||
|
|
aaeb2bd110 | ||
|
|
8d6a03820a | ||
|
|
5544f98add | ||
|
|
8131c77860 | ||
|
|
fdfa7e6cc2 | ||
|
|
3f4e917ad6 | ||
|
|
937940c989 | ||
|
|
775a1fbc6d | ||
|
|
45999b69d6 | ||
|
|
90c8bd93e0 | ||
|
|
0c358c37f5 | ||
|
|
6b237de909 | ||
|
|
3323f31cfb | ||
|
|
36ed7f507e | ||
|
|
99e461c676 | ||
|
|
767e38f462 | ||
|
|
733e404fcf | ||
|
|
29002a1c83 | ||
|
|
97142bb8db | ||
|
|
9d8425bd72 | ||
|
|
af6f3bffab | ||
|
|
77a92e6dcc | ||
|
|
2cfde4dfd9 | ||
|
|
1016ab1c2a | ||
|
|
404e89da4d | ||
|
|
8399ed900a | ||
|
|
b238bc691d | ||
|
|
5553fbd537 | ||
|
|
b5989a6b26 | ||
|
|
fa3120cb40 | ||
|
|
fd3ef4cdfe | ||
|
|
94a61389ff | ||
|
|
2c17b16328 | ||
|
|
f3a567b65d | ||
|
|
47c722d674 | ||
|
|
561a1a64f2 | ||
|
|
6e9d60ef70 | ||
|
|
52c378b447 | ||
|
|
cdc7396f97 | ||
|
|
e5012bd07e | ||
|
|
eeb0aaa09e | ||
|
|
bf82b441ae | ||
|
|
a523aa3ef5 | ||
|
|
bc807a18d1 | ||
|
|
abe58c867e | ||
|
|
453b5ded1d | ||
|
|
453722ba54 | ||
|
|
5d6e6f79b9 | ||
|
|
793003d0fa | ||
|
|
7b0e6e2fc4 | ||
|
|
67863ec495 | ||
|
|
ab37f89f55 | ||
|
|
2723504473 | ||
|
|
0ddadc98a3 | ||
|
|
8f02730e1f | ||
|
|
29b32be97c | ||
|
|
49848eaed5 | ||
|
|
b209c6dcbb | ||
|
|
65ff8bd160 | ||
|
|
5d1bb42c18 | ||
|
|
faaf59ccb3 | ||
|
|
85f75f1ccd | ||
|
|
f73c6f875c | ||
|
|
22ccf6c368 | ||
|
|
c04e4f179f | ||
|
|
a797dca528 | ||
|
|
55f1a63faf | ||
|
|
ad50a70440 | ||
|
|
639557d975 | ||
|
|
3ac080fc80 | ||
|
|
03e2618d35 | ||
|
|
b94e5f7855 | ||
|
|
3624149344 | ||
|
|
3a39475d20 | ||
|
|
8f76fe1d7f | ||
|
|
57e380fa99 | ||
|
|
52b51df859 | ||
|
|
aeabbd305c | ||
|
|
7388efa953 | ||
|
|
ed6957302f | ||
|
|
76a4082de7 | ||
|
|
0ea4c3c06b | ||
|
|
15ec487fde | ||
|
|
4f3b391674 | ||
|
|
4ba62a6b45 | ||
|
|
4715fa16ae | ||
|
|
cb5c296829 | ||
|
|
3026eda86a | ||
|
|
f6f094213e | ||
|
|
aff8758fe4 | ||
|
|
349a77cb55 | ||
|
|
c6a516f122 | ||
|
|
9050307dfe | ||
|
|
7c6c74dff0 | ||
|
|
b99d5df922 | ||
|
|
f7793840e1 | ||
|
|
85e76a7cfc | ||
|
|
378884660a | ||
|
|
3cd6d4e5fc | ||
|
|
8a9516a973 | ||
|
|
af0ecca492 | ||
|
|
a8f1918d88 | ||
|
|
aae441951b | ||
|
|
0b79d07d34 | ||
|
|
3c6c1e36ec | ||
|
|
8bc153e142 | ||
|
|
82b7ca92ad | ||
|
|
6ace4f6fa4 | ||
|
|
454d00e2ae | ||
|
|
54f33f9585 | ||
|
|
66308774db | ||
|
|
03a6d77ef4 | ||
|
|
0765355a4e | ||
|
|
743359a6bf | ||
|
|
4eaf5e218a | ||
|
|
d61959b583 | ||
|
|
a845f211e3 | ||
|
|
315aa1fcd8 | ||
|
|
b503d68045 | ||
|
|
87fd90716f | ||
|
|
b1015dedd7 | ||
|
|
79173c0f2a | ||
|
|
f688309b3a | ||
|
|
d7ceea0608 | ||
|
|
941a12cb4e | ||
|
|
3cad00fdcc | ||
|
|
7a4fffca24 | ||
|
|
935552427c | ||
|
|
9edab21385 | ||
|
|
eab6d483a5 | ||
|
|
90e740eb5f | ||
|
|
1132ef7554 | ||
|
|
06798a2b35 | ||
|
|
516c708fc7 | ||
|
|
041754f255 | ||
|
|
6b94c32cd6 | ||
|
|
1dc3ae6e4e | ||
|
|
ae94fe04ef | ||
|
|
cc164b0dc3 | ||
|
|
8e89a136e1 | ||
|
|
d3703ba80f | ||
|
|
e4353f2119 | ||
|
|
a4a0ccdce3 | ||
|
|
7ee8ee8b7e | ||
|
|
9ff446e6f9 | ||
|
|
a4f3312d9d | ||
|
|
d6dbf15a1f | ||
|
|
724673be83 | ||
|
|
0860f46220 | ||
|
|
28a7a325e8 | ||
|
|
ccfe4fefeb | ||
|
|
375b28650b | ||
|
|
6a759e7cef | ||
|
|
ece61944f4 | ||
|
|
61b2e086b3 | ||
|
|
e9913a11c1 | ||
|
|
81f71522b6 | ||
|
|
1eff11f947 | ||
|
|
801b87b48a | ||
|
|
aa817a1475 | ||
|
|
05e6fba6c3 | ||
|
|
68bf54607a | ||
|
|
e261e16981 | ||
|
|
8a163e3db0 | ||
|
|
5ecc88cb33 | ||
|
|
a0b565a8e8 | ||
|
|
99578f1bd0 | ||
|
|
81becd5e66 | ||
|
|
275b574ace | ||
|
|
85e709705b | ||
|
|
8915c18f8a | ||
|
|
fd0539b4ba | ||
|
|
42d819e796 | ||
|
|
c142b9b9e5 | ||
|
|
678a7b53f7 | ||
|
|
bda63abb40 | ||
|
|
b5ea92a26e | ||
|
|
dbd4e0522e | ||
|
|
d90a35af19 | ||
|
|
f9fba35d1d | ||
|
|
b12ab825a1 | ||
|
|
95d691afdb | ||
|
|
f5ebeb4c4d | ||
|
|
26bf1e8499 | ||
|
|
e384c7c014 | ||
|
|
4c2622755d | ||
|
|
60e81e5e63 | ||
|
|
0b57054ed3 | ||
|
|
bdbeaf97d6 | ||
|
|
45581dbaca | ||
|
|
99d39909c4 | ||
|
|
fc15d72038 | ||
|
|
30f514cf20 | ||
|
|
ecb75b69fd | ||
|
|
68e27f8188 | ||
|
|
778a475136 | ||
|
|
74d0edec0f | ||
|
|
38068e6df0 | ||
|
|
b0dd5d9157 | ||
|
|
47b8f78cb0 | ||
|
|
9d745be3f7 | ||
|
|
a4acf7b67b | ||
|
|
566a360d5f | ||
|
|
4f89cc73e6 | ||
|
|
c9d29d109e | ||
|
|
73612b004f | ||
|
|
c690447dd9 | ||
|
|
7522b53423 | ||
|
|
c0fb62531e | ||
|
|
987631b9a0 | ||
|
|
0070612296 | ||
|
|
39c376f0c3 | ||
|
|
6ba469e7a4 | ||
|
|
40a35db784 | ||
|
|
96e8a3c725 | ||
|
|
0e39b77d4e | ||
|
|
dbb6d20aac | ||
|
|
76295c7a13 | ||
|
|
16ef01dc69 | ||
|
|
92436021ab | ||
|
|
821c70f5d7 | ||
|
|
cecdfdb0c0 | ||
|
|
41c6914454 | ||
|
|
a6e4e89592 | ||
|
|
aceb08f938 | ||
|
|
f5aee6a6e6 | ||
|
|
8ee6f8227e | ||
|
|
a30c98c1a2 | ||
|
|
5cf9ccf6ab | ||
|
|
710c853adc | ||
|
|
37304aba2d | ||
|
|
65baf502b7 | ||
|
|
0e31eb458e | ||
|
|
573cc7d36f | ||
|
|
6ad0a157e3 | ||
|
|
d3ce5c3504 | ||
|
|
b9a06e68dd | ||
|
|
ecee175962 | ||
|
|
0f1109a9a2 | ||
|
|
61de08b0dd | ||
|
|
6181c39f05 | ||
|
|
e88226c256 | ||
|
|
a3ce95e482 | ||
|
|
d96b8c317a | ||
|
|
818d1de771 | ||
|
|
099b5552c4 | ||
|
|
8352e7e9ec | ||
|
|
d8fda48551 | ||
|
|
5362c7ac50 | ||
|
|
01ad387ac8 | ||
|
|
3e7b786af5 | ||
|
|
eba6789e6c | ||
|
|
5272bd899b | ||
|
|
0aab67f0aa | ||
|
|
6a58e173b8 | ||
|
|
36e685580a | ||
|
|
8438b8aa92 | ||
|
|
64f26be053 | ||
|
|
c30bba8c63 | ||
|
|
a593d8a518 | ||
|
|
fbaeb55c15 | ||
|
|
13f0737883 | ||
|
|
6afea0e81c | ||
|
|
5f3b9876b8 | ||
|
|
e477ce93e9 | ||
|
|
39e728622f | ||
|
|
9254d2846f | ||
|
|
91d35f01f2 | ||
|
|
e4e8a903c3 | ||
|
|
55e34c5464 | ||
|
|
e57da86baf | ||
|
|
bab7a2df80 | ||
|
|
1ad68de8b8 | ||
|
|
94b91ee4af | ||
|
|
af843a9517 | ||
|
|
2a5d01a930 | ||
|
|
8ec94418de | ||
|
|
e132e95476 | ||
|
|
a849ce9942 | ||
|
|
007efdb852 | ||
|
|
1cf5a56896 | ||
|
|
a401169ea8 | ||
|
|
7670e93639 | ||
|
|
66fd3b9768 | ||
|
|
fda2e89a1e | ||
|
|
57486a1f61 | ||
|
|
364476c1cd | ||
|
|
b2f52dd22e | ||
|
|
aaf0cc00c4 | ||
|
|
f784381c32 | ||
|
|
a8f9d99cae | ||
|
|
51323482b2 | ||
|
|
8b6993f7aa | ||
|
|
447ffb23d5 | ||
|
|
4813ab2d28 | ||
|
|
02fdf8271d | ||
|
|
829800f272 | ||
|
|
f59f13efd5 | ||
|
|
94b9898ca7 | ||
|
|
5a23ec4dc4 | ||
|
|
817bbb4bf9 | ||
|
|
577290aaba | ||
|
|
a96df34d9b | ||
|
|
c89e11c8fa | ||
|
|
6cb9985e5d | ||
|
|
a9ed6d5a24 | ||
|
|
10f6f234ff | ||
|
|
2156408d45 | ||
|
|
67aabbff8f | ||
|
|
17696bc679 | ||
|
|
da660b234c | ||
|
|
383db0dc81 | ||
|
|
16e1a2716e | ||
|
|
5ddd229b95 | ||
|
|
d101f2113b | ||
|
|
1e2c5cc151 | ||
|
|
1544544f8a | ||
|
|
5d5b625d0e | ||
|
|
194d4e9ffd | ||
|
|
47d3759474 | ||
|
|
dc6c19f560 | ||
|
|
878b85c421 | ||
|
|
17a4a2527d | ||
|
|
61c33ca24e | ||
|
|
5b7b704365 | ||
|
|
123b6f88dc | ||
|
|
cd4e4fb351 | ||
|
|
045aa45731 | ||
|
|
36feac0d25 | ||
|
|
48516fded2 | ||
|
|
fd8703bd2a | ||
|
|
23fc2ef0bd | ||
|
|
18814c03d4 | ||
|
|
ab5bbfa74b | ||
|
|
3462b53fbc | ||
|
|
07548918df | ||
|
|
37d56b0e8a | ||
|
|
e5f54a9dbd | ||
|
|
0db8b00b8a | ||
|
|
4745895e22 | ||
|
|
a74f3f9fd7 | ||
|
|
3543d8170c | ||
|
|
cde4072f25 | ||
|
|
66c693eebb | ||
|
|
e6f36f2dc5 | ||
|
|
624ad1bd8b | ||
|
|
74817c35f3 | ||
|
|
5f549aab2e | ||
|
|
79449cce57 | ||
|
|
af13acdc29 | ||
|
|
5ffe5474ac | ||
|
|
cfb18ba537 | ||
|
|
3acd445f94 | ||
|
|
c23b66b1de | ||
|
|
32d5985ad2 | ||
|
|
8b800df720 | ||
|
|
a35d5e3a3a | ||
|
|
0b7058d8ef | ||
|
|
c18d2a359c | ||
|
|
4820b64a7f | ||
|
|
e014d268fe | ||
|
|
9f7d8c338e | ||
|
|
5275f29efe | ||
|
|
41890f15b9 | ||
|
|
870389b3ba | ||
|
|
9463a7c594 | ||
|
|
5951314f5d | ||
|
|
153472d70d | ||
|
|
2955b20f2e | ||
|
|
c06cc31d85 | ||
|
|
90a8e643b2 | ||
|
|
abe8e40597 | ||
|
|
d790300215 | ||
|
|
4bf96e99b3 | ||
|
|
fa09c8af61 | ||
|
|
c01dff8263 | ||
|
|
06274ff5a5 | ||
|
|
66552c228c | ||
|
|
1e897561e8 | ||
|
|
bc020da4f5 | ||
|
|
99102af79e | ||
|
|
8fd8177008 | ||
|
|
e7aea584f5 | ||
|
|
f4faa3646e | ||
|
|
3db4402f3c | ||
|
|
975be7a2c9 | ||
|
|
527720fb5b | ||
|
|
5ea9097dbd | ||
|
|
5f82322ffa | ||
|
|
d6f183fbb9 | ||
|
|
3442d4d463 | ||
|
|
6ee5a1e492 | ||
|
|
a4a790030d | ||
|
|
8ce94d5bd3 | ||
|
|
2575d1dd70 | ||
|
|
41e29d7384 | ||
|
|
e08cf27b8a | ||
|
|
e14d65d704 | ||
|
|
ec31b39989 | ||
|
|
da723ca11d | ||
|
|
3119f936ab | ||
|
|
7bb4c8521a | ||
|
|
c08a2871e6 | ||
|
|
f4c4787281 | ||
|
|
e335f19a4d | ||
|
|
7754647e71 | ||
|
|
ccbc6183c3 | ||
|
|
ea12a1de85 | ||
|
|
4ecd26ce77 | ||
|
|
f280d8db13 | ||
|
|
7a186ba1b0 | ||
|
|
8911e666a0 | ||
|
|
848494b20f | ||
|
|
c62ae777c2 | ||
|
|
65b7b22c09 | ||
|
|
abdd8feebb | ||
|
|
3b8c9a407f | ||
|
|
6451c57e52 | ||
|
|
432b25f755 | ||
|
|
6739d5b99f | ||
|
|
b0e99a56cb | ||
|
|
d3eede2110 | ||
|
|
8c84bcba72 | ||
|
|
ecbe5a66f2 | ||
|
|
4e5e154603 | ||
|
|
6d061ec903 | ||
|
|
fabe0493c2 | ||
|
|
66199b1efe | ||
|
|
23f933a78d | ||
|
|
e8464e0f61 | ||
|
|
79ed36495b | ||
|
|
b74eb56710 | ||
|
|
3b3c3210a6 | ||
|
|
ae09a46cb8 | ||
|
|
bf7f0bf52c | ||
|
|
4d67a2ba8b | ||
|
|
98f8594151 | ||
|
|
c025dfbfa7 | ||
|
|
a25cb988bb | ||
|
|
acab9e7ae4 | ||
|
|
f3687f7177 | ||
|
|
8f43567a68 | ||
|
|
2230b2c8bc | ||
|
|
8de26e434c | ||
|
|
8f65322a84 | ||
|
|
20212ee823 | ||
|
|
d0f8fb9b93 | ||
|
|
f36c909528 | ||
|
|
cd83bfb31c | ||
|
|
c6420792f2 | ||
|
|
03ea45046d | ||
|
|
290c40a4ab | ||
|
|
47a5851d45 | ||
|
|
3050f06a8d | ||
|
|
13dfb5568d | ||
|
|
d9c649d26e | ||
|
|
75115e1d83 | ||
|
|
c17e05040a | ||
|
|
667ac172df | ||
|
|
c7dac035ae | ||
|
|
63e0140ae6 | ||
|
|
1671879b7a | ||
|
|
ff81e17504 | ||
|
|
708539c559 | ||
|
|
fd0edae75a | ||
|
|
d9252b3645 | ||
|
|
eb1fbaabce | ||
|
|
36b3963efb | ||
|
|
b582697889 | ||
|
|
41070f6768 | ||
|
|
118131109e | ||
|
|
80cdfc9e0a | ||
|
|
1d98c9849e | ||
|
|
7dfb1c2e97 | ||
|
|
4af5f572f4 | ||
|
|
c057f067c7 | ||
|
|
e96d653c9e | ||
|
|
ce7d0a7015 | ||
|
|
5cab04075e | ||
|
|
0465528431 | ||
|
|
0fcc8918dd | ||
|
|
cdf122baa0 | ||
|
|
7df75c00c7 | ||
|
|
d0d2c4cb49 | ||
|
|
dbf60eb922 | ||
|
|
a64181f14f | ||
|
|
07ff47f103 | ||
|
|
611e510c49 | ||
|
|
0483548a39 | ||
|
|
fb261c0bd5 | ||
|
|
cc13b0ea05 | ||
|
|
d772e1489b | ||
|
|
dca0377e19 | ||
|
|
cbb71baca9 | ||
|
|
045307ea0f | ||
|
|
f29768c404 | ||
|
|
c0f155f6ff | ||
|
|
8dede8f8a4 | ||
|
|
d28ee9a25e | ||
|
|
c3544dc090 | ||
|
|
3c90032369 | ||
|
|
e91d436e45 | ||
|
|
c3d5f8e766 | ||
|
|
080350a745 | ||
|
|
f687725e97 | ||
|
|
4170b8c32e | ||
|
|
902382f622 | ||
|
|
25f739c183 | ||
|
|
6a2d152086 | ||
|
|
093dd98101 | ||
|
|
de28d3a655 | ||
|
|
e76c187efb | ||
|
|
e35ebbf813 | ||
|
|
04f7d96623 | ||
|
|
55693b1168 | ||
|
|
26dec992eb | ||
|
|
d3fde5188e | ||
|
|
3b583c150f | ||
|
|
1405fd1fef | ||
|
|
adfb289e81 | ||
|
|
a51f378ecc | ||
|
|
b5d1eb42b4 | ||
|
|
678ec0bd04 | ||
|
|
12a7293b31 | ||
|
|
bb0298bc71 | ||
|
|
abf87b000d | ||
|
|
7eaf1c76dc | ||
|
|
1f3a2e900c | ||
|
|
770c2ade05 | ||
|
|
95b62ef980 | ||
|
|
25e2b07010 | ||
|
|
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 | ||
|
|
d8a60daece | ||
|
|
76d4f65ff9 | ||
|
|
68cba2a1fb | ||
|
|
02460ff864 | ||
|
|
c61fdff729 | ||
|
|
777816cb99 | ||
|
|
89fea85a45 | ||
|
|
b748a63a43 | ||
|
|
d07a149e2c | ||
|
|
c78aa138b0 | ||
|
|
e8adb5ab57 | ||
|
|
627bc23b1c | ||
|
|
96e6839745 | ||
|
|
2d5162dc3c | ||
|
|
732a5fd0b2 | ||
|
|
0eeda99a8c | ||
|
|
972c6f0cae | ||
|
|
04acc88023 | ||
|
|
b8e2edc99f | ||
|
|
f21275b910 | ||
|
|
a57b6326e3 | ||
|
|
84590ec0a4 | ||
|
|
64e6e7a0ae | ||
|
|
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 | ||
|
|
2c87e84b0a | ||
|
|
fab35cb307 | ||
|
|
74aff89918 | ||
|
|
6f3f3bb30c | ||
|
|
a14f22f65b | ||
|
|
ac412feb69 | ||
|
|
b022232e84 | ||
|
|
0b257cfcef | ||
|
|
92b9ed8342 | ||
|
|
5305842763 | ||
|
|
0fca7769e8 | ||
|
|
3c28283377 | ||
|
|
aea18f6e74 | ||
|
|
1916610b83 | ||
|
|
12b1c99962 | ||
|
|
0073ff3acd | ||
|
|
0f711963d7 | ||
|
|
2ea4d7fd02 | ||
|
|
36a74daa0a | ||
|
|
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 | ||
|
|
49b68c38fa | ||
|
|
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 | ||
|
|
44914c17bc | ||
|
|
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 | ||
|
|
fa72a98635 | ||
|
|
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 | ||
|
|
d7c1c0b1f6 | ||
|
|
835fa31d56 | ||
|
|
d049fd3929 | ||
|
|
9b6247a507 | ||
|
|
c94e0177c2 | ||
|
|
d2e58193d2 | ||
|
|
0ad3017df7 | ||
|
|
6163d214b3 | ||
|
|
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 | ||
|
|
bc5bc0f026 | ||
|
|
a241197067 | ||
|
|
252353d1c6 | ||
|
|
ec40053720 | ||
|
|
3cd9cb8911 | ||
|
|
2dbae95a7e | ||
|
|
c852e9958b | ||
|
|
9b397f1e28 | ||
|
|
c8685c2002 | ||
|
|
11ddfbba4e | ||
|
|
56bbc17ddc | ||
|
|
65f57e5da7 | ||
|
|
5f47b85b87 | ||
|
|
004aadfe70 | ||
|
|
9423390c2e | ||
|
|
f394632319 | ||
|
|
667d0ef319 | ||
|
|
ceb8566970 | ||
|
|
f62b83fb77 | ||
|
|
822ed84225 | ||
|
|
a9d5e26748 | ||
|
|
506c8cd964 | ||
|
|
9eb135fd73 | ||
|
|
6b4c2e8dc0 | ||
|
|
ab3677d64c | ||
|
|
bd20288b81 | ||
|
|
1d8355f54b | ||
|
|
38cc22a85c | ||
|
|
e17519e49b | ||
|
|
d925b96daf | ||
|
|
df419fd862 | ||
|
|
954ffa102f | ||
|
|
bdf4006da7 | ||
|
|
859e2d5578 | ||
|
|
5c1928b14d | ||
|
|
e0040af7e5 | ||
|
|
c6ec70b67b | ||
|
|
c110795718 | ||
|
|
099e3030bf | ||
|
|
60ac08115f | ||
|
|
6ff431d464 | ||
|
|
5b120186f1 | ||
|
|
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 | ||
|
|
50227f12fd | ||
|
|
72422b32dc | ||
|
|
fd0d28afc3 | ||
|
|
ff8ce12787 | ||
|
|
2c577b1360 | ||
|
|
2e8af3a8b7 | ||
|
|
1173106a20 | ||
|
|
c9a0b9a45c | ||
|
|
73f00732cf | ||
|
|
db1e86b3d9 | ||
|
|
55aa82f814 | ||
|
|
3f27c09728 | ||
|
|
6e3b7f4ea2 | ||
|
|
73f4e8b2af | ||
|
|
88b264cfce | ||
|
|
a902e2a9de | ||
|
|
ac87ddfb05 | ||
|
|
16f2b119eb | ||
|
|
7f2c6a9d80 | ||
|
|
1818af1c3e | ||
|
|
8e77c39deb | ||
|
|
0dbc11e37d | ||
|
|
58d902eb78 | ||
|
|
d0801fdbab | ||
|
|
9f9d92b2df | ||
|
|
7a93422089 | ||
|
|
7dc322273c | ||
|
|
19273c7b2d | ||
|
|
d7eb709a9c | ||
|
|
a5ad8090cf | ||
|
|
35ae2cd1a5 | ||
|
|
dae40afffb | ||
|
|
5eb2d16acd | ||
|
|
340b14f0b7 | ||
|
|
1cdd082a9e | ||
|
|
160e81e901 | ||
|
|
b5f03a36d5 | ||
|
|
55e0690f69 | ||
|
|
4ea18083f7 | ||
|
|
b649b48eae | ||
|
|
c17ee8a914 | ||
|
|
1bcd90d45d | ||
|
|
422e95db9c | ||
|
|
7a41ab6982 | ||
|
|
e5ceddabac | ||
|
|
d50792dec9 | ||
|
|
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 | ||
|
|
965735febb | ||
|
|
1d05f41a70 | ||
|
|
180f4d0929 | ||
|
|
5ac7810480 | ||
|
|
a3c4a70ba3 | ||
|
|
2a73783bc6 | ||
|
|
df6edb50e9 | ||
|
|
6cae05d058 | ||
|
|
cf6fc7c741 | ||
|
|
46a39b1e0f | ||
|
|
8b2f933a51 | ||
|
|
2393d829de | ||
|
|
db007fbb2e | ||
|
|
d0c9c1de57 | ||
|
|
190b6d629b | ||
|
|
dfcb241850 | ||
|
|
2561b68af8 | ||
|
|
c48612e516 | ||
|
|
595bd2e3c4 | ||
|
|
bb79b2d19b | ||
|
|
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 | ||
|
|
d833293581 | ||
|
|
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 | ||
|
|
cd6d6c6280 | ||
|
|
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 | ||
|
|
47486db37b | ||
|
|
14a74c8e4b | ||
|
|
0b2cea6e9f | ||
|
|
a63383dd19 | ||
|
|
a023b005c6 | ||
|
|
dd3c8487f1 | ||
|
|
19d96d5b26 | ||
|
|
9691fe9dae | ||
|
|
69dbc36a1c | ||
|
|
8b7d1cdc27 | ||
|
|
d1fc5fe432 | ||
|
|
13b81debb3 | ||
|
|
37cbb0bdea | ||
|
|
7dbf01b210 | ||
|
|
60f29236f6 | ||
|
|
8fed003ce5 | ||
|
|
9ae07082ff | ||
|
|
2ed9e2d9a8 | ||
|
|
1fdaf74c4f | ||
|
|
656543c5ca | ||
|
|
21d2b78105 | ||
|
|
d7599ab16d | ||
|
|
229df65cfc | ||
|
|
521ef3f579 | ||
|
|
cf8c9770a0 | ||
|
|
4d25986aaa | ||
|
|
a2b1f4221b | ||
|
|
dfaac25a37 | ||
|
|
ea75dc7064 | ||
|
|
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 | ||
|
|
7b659b2741 | ||
|
|
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 | ||
|
|
32cbf52310 | ||
|
|
acda125e8b | ||
|
|
d4d34c1457 | ||
|
|
ecafe5306f | ||
|
|
4ea38327b6 | ||
|
|
b83b0ed06a | ||
|
|
1544965b21 | ||
|
|
8089afd453 | ||
|
|
30198ee8c1 | ||
|
|
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 | ||
|
|
2d21f3c501 | ||
|
|
fdff6b2b01 | ||
|
|
57f8128718 | ||
|
|
cdd65095e3 | ||
|
|
bc604d14ff | ||
|
|
e3a4f23c9d | ||
|
|
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 |
28
.gitignore
vendored
28
.gitignore
vendored
@@ -15,10 +15,26 @@ GPATH
|
||||
.#*
|
||||
\#*#
|
||||
|
||||
# Example project files
|
||||
examples/*/sdkconfig
|
||||
examples/*/sdkconfig.old
|
||||
examples/*/build
|
||||
# eclipse setting
|
||||
.settings
|
||||
|
||||
# Example project files
|
||||
examples/**/sdkconfig
|
||||
examples/**/sdkconfig.old
|
||||
examples/**/build
|
||||
|
||||
#Doc build artifacts
|
||||
docs/_build/
|
||||
docs/doxygen-warning-log.txt
|
||||
docs/sphinx-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
|
||||
|
||||
# AWS IoT Examples require device-specific certs/keys
|
||||
examples/protocols/aws_iot/*/main/certs/*.pem.*
|
||||
|
||||
# Bootloader files
|
||||
components/bootloader/src/sdkconfig.old
|
||||
642
.gitlab-ci.yml
642
.gitlab-ci.yml
@@ -1,8 +1,27 @@
|
||||
stages:
|
||||
- build
|
||||
- assign_test
|
||||
- unit_test
|
||||
- test
|
||||
- test_report
|
||||
- deploy
|
||||
|
||||
variables:
|
||||
# System environment
|
||||
|
||||
# Common parameters for the 'make' during CI tests
|
||||
MAKEFLAGS: "-j5 --no-keep-going"
|
||||
|
||||
# GitLab-CI environment
|
||||
|
||||
# more attempts for more robust
|
||||
GET_SOURCES_ATTEMPTS: "10"
|
||||
ARTIFACT_DOWNLOAD_ATTEMPTS: "10"
|
||||
|
||||
# IDF environment
|
||||
|
||||
IDF_PATH: "$CI_PROJECT_DIR"
|
||||
|
||||
before_script:
|
||||
# add gitlab ssh key
|
||||
- mkdir -p ~/.ssh
|
||||
@@ -12,150 +31,247 @@ 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
|
||||
|
||||
build_template_app:
|
||||
stage: build
|
||||
image: espressif/esp32-ci-env
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env:v2.1
|
||||
tags:
|
||||
- build
|
||||
|
||||
variables:
|
||||
SDK_PATH: "$CI_PROJECT_DIR"
|
||||
IDF_PATH: "$CI_PROJECT_DIR"
|
||||
GIT_STRATEGY: clone
|
||||
|
||||
BATCH_BUILD: "1"
|
||||
IDF_CI_BUILD: "1"
|
||||
script:
|
||||
- git clone https://github.com/espressif/esp-idf-template.git
|
||||
- cd esp-idf-template
|
||||
# Try to use the same branch name for esp-idf-template that we're
|
||||
# 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
|
||||
- git checkout ${CI_COMMIT_REF_NAME} || echo "Using esp-idf-template default branch..."
|
||||
# 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
|
||||
.build_template: &build_template
|
||||
stage: build
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env:v2.1
|
||||
tags:
|
||||
- build
|
||||
image: espressif/esp32-ci-env
|
||||
|
||||
variables:
|
||||
SDK_PATH: "$CI_PROJECT_DIR"
|
||||
IDF_PATH: "$CI_PROJECT_DIR"
|
||||
GIT_STRATEGY: clone
|
||||
BATCH_BUILD: "1"
|
||||
V: "0"
|
||||
|
||||
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 $SSC_REPOSITORY
|
||||
- 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
|
||||
- git checkout ${CI_COMMIT_REF_NAME} || echo "Using SSC default branch..."
|
||||
- MAKEFLAGS= ./gen_misc_ng.sh
|
||||
|
||||
build_examples:
|
||||
build_esp_idf_tests:
|
||||
<<: *build_template
|
||||
artifacts:
|
||||
paths:
|
||||
- build_examples/*/*/build/*.bin
|
||||
- build_examples/*/*/build/*.elf
|
||||
- build_examples/*/*/build/*.map
|
||||
- build_examples/*/*/build/bootloader/*.bin
|
||||
- tools/unit-test-app/build/*.bin
|
||||
- tools/unit-test-app/build/*.elf
|
||||
- tools/unit-test-app/build/*.map
|
||||
- tools/unit-test-app/build/download.config
|
||||
- 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
|
||||
- make TESTS_ALL=1
|
||||
# cut last line in case make V=0/1 is set by default
|
||||
- make print_flash_cmd | tail -n 1 > build/download.config
|
||||
- python tools/UnitTestParser.py
|
||||
|
||||
.build_examples_template: &build_examples_template
|
||||
<<: *build_template
|
||||
artifacts:
|
||||
paths:
|
||||
- build_examples/*/*/*/build/*.bin
|
||||
- build_examples/*/*/*/build/*.elf
|
||||
- build_examples/*/*/*/build/*.map
|
||||
- build_examples/*/*/*/build/bootloader/*.bin
|
||||
expire_in: 1 week
|
||||
variables:
|
||||
IDF_CI_BUILD: "1"
|
||||
GIT_STRATEGY: fetch
|
||||
script:
|
||||
# it's not possible to build 100% out-of-tree and have the "artifacts"
|
||||
# mechanism work, but this is the next best thing
|
||||
- mkdir build_examples
|
||||
- cd build_examples
|
||||
- ${IDF_PATH}/make/build_examples.sh
|
||||
# build some of examples
|
||||
- ${IDF_PATH}/make/build_examples.sh "${CI_JOB_NAME}"
|
||||
|
||||
build_examples_00:
|
||||
<<: *build_examples_template
|
||||
|
||||
build_examples_01:
|
||||
<<: *build_examples_template
|
||||
|
||||
build_examples_02:
|
||||
<<: *build_examples_template
|
||||
|
||||
build_examples_03:
|
||||
<<: *build_examples_template
|
||||
|
||||
build_examples_04:
|
||||
<<: *build_examples_template
|
||||
|
||||
build_docs:
|
||||
stage: build
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env:v2.1
|
||||
tags:
|
||||
- build_docs
|
||||
artifacts:
|
||||
paths:
|
||||
- docs/_build/html
|
||||
expire_in: 1 mos
|
||||
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
|
||||
|
||||
test_nvs_on_host:
|
||||
stage: test
|
||||
image: espressif/esp32-ci-env
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env:v2.1
|
||||
tags:
|
||||
- nvs_host_test
|
||||
dependencies: []
|
||||
script:
|
||||
- cd components/nvs_flash/test
|
||||
- cd components/nvs_flash/test_nvs_host
|
||||
- make test
|
||||
|
||||
test_partition_table_on_host:
|
||||
stage: test
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env:v2.1
|
||||
tags:
|
||||
- build
|
||||
dependencies: []
|
||||
script:
|
||||
- cd components/partition_table/test_gen_esp32part_host
|
||||
- ./gen_esp32part_tests.py
|
||||
|
||||
test_wl_on_host:
|
||||
stage: test
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env:v2.1
|
||||
tags:
|
||||
- wl_host_test
|
||||
artifacts:
|
||||
paths:
|
||||
- components/wear_levelling/test_wl_host/coverage_report.zip
|
||||
dependencies: []
|
||||
script:
|
||||
- cd components/wear_levelling/test_wl_host
|
||||
- make test
|
||||
|
||||
test_build_system:
|
||||
stage: test
|
||||
image: espressif/esp32-ci-env
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env:v2.1
|
||||
tags:
|
||||
- build_test
|
||||
variables:
|
||||
IDF_PATH: "$CI_PROJECT_DIR"
|
||||
dependencies: []
|
||||
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: $CI_DOCKER_REGISTRY/esp32-ci-env:v2.1
|
||||
tags:
|
||||
- report
|
||||
only:
|
||||
- master
|
||||
- triggers
|
||||
|
||||
- /^release\/v/
|
||||
- /^v\d+\.\d+(\.\d+)?($|-)/
|
||||
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_COMMIT_SHA"
|
||||
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/tools/ModuleDefinition.yml"
|
||||
#dependencies:
|
||||
#We need all UT* and IT* artifacts except for only a few other
|
||||
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_COMMIT_SHA | cut -c 1-7`
|
||||
- REVISION="${VER_NUM}_${SHA_ID}"
|
||||
# replace / to _ in branch name
|
||||
- ESCAPED_BRANCH_NAME=`echo $CI_COMMIT_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_JOB_ID/artifacts/browse/$CI_COMMIT_SHA"
|
||||
# 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_COMMIT_REF_NAME/$CI_COMMIT_SHA, 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
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env:v2.1
|
||||
tags:
|
||||
- deploy
|
||||
only:
|
||||
- master
|
||||
- /^release\/v/
|
||||
- /^v\d+\.\d+(\.\d+)?($|-)/
|
||||
when: on_success
|
||||
image: espressif/esp32-ci-env
|
||||
dependencies: []
|
||||
variables:
|
||||
GIT_STRATEGY: clone
|
||||
GITHUB_PUSH_REFS: refs/remotes/origin/release refs/remotes/origin/master
|
||||
script:
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 700 ~/.ssh
|
||||
@@ -164,4 +280,390 @@ 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_COMMIT_SHA 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
|
||||
- eval $(git for-each-ref --shell bash --format 'if [ $CI_COMMIT_SHA == %(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
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env:v2.1
|
||||
tags:
|
||||
- deploy
|
||||
only:
|
||||
- master
|
||||
- /^release\/v/
|
||||
- /^v\d+\.\d+(\.\d+)?($|-)/
|
||||
- triggers
|
||||
dependencies:
|
||||
- build_docs
|
||||
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: $CI_DOCKER_REGISTRY/esp32-ci-env:v2.1
|
||||
tags:
|
||||
- check_doc_links
|
||||
only:
|
||||
# can only be triggered
|
||||
- triggers
|
||||
artifacts:
|
||||
paths:
|
||||
- docs/_build/linkcheck
|
||||
expire_in: 1 mos
|
||||
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_COMMIT_REF_NAME}" = "master" || exit 0
|
||||
- cd docs
|
||||
- make linkcheck
|
||||
|
||||
check_commit_msg:
|
||||
stage: deploy
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env:v2.1
|
||||
tags:
|
||||
- build
|
||||
except:
|
||||
- master
|
||||
- /^release\/v/
|
||||
- /^v\d+\.\d+(\.\d+)?($|-)/
|
||||
dependencies: []
|
||||
before_script:
|
||||
- echo "skip update submodule"
|
||||
script:
|
||||
- git checkout ${CI_COMMIT_REF_NAME}
|
||||
# commit start with "WIP: " need to be squashed before merge
|
||||
- 'git log --pretty=%s master..${CI_COMMIT_REF_NAME} | grep "^WIP: " || exit 0 && exit 1'
|
||||
|
||||
check_submodule_sync:
|
||||
stage: deploy
|
||||
image: $CI_DOCKER_REGISTRY/esp32-ci-env:v2.1
|
||||
tags:
|
||||
- build
|
||||
except:
|
||||
- master
|
||||
- /^release\/v/
|
||||
- /^v\d+\.\d+(\.\d+)?($|-)/
|
||||
dependencies: []
|
||||
before_script:
|
||||
- echo "do not use gitlab submodule repository"
|
||||
script:
|
||||
# check if all submodules are correctly synced to public repostory
|
||||
- git submodule update --init --recursive
|
||||
|
||||
assign_test:
|
||||
<<: *build_template
|
||||
stage: assign_test
|
||||
dependencies:
|
||||
- build_esp_idf_tests
|
||||
- build_ssc
|
||||
artifacts:
|
||||
paths:
|
||||
- test_bins
|
||||
- components/idf_test/*/CIConfigs
|
||||
- components/idf_test/*/TC.sqlite
|
||||
expire_in: 1 mos
|
||||
script:
|
||||
# first move test bins together: test_bins/CHIP_SDK/TestApp/bin_files
|
||||
- mkdir -p test_bins/ESP32_IDF/UT
|
||||
- cp -r tools/unit-test-app/build/* test_bins/ESP32_IDF/UT
|
||||
- cp -r SSC/ssc_bin/* test_bins/ESP32_IDF
|
||||
# clone test script to assign tests
|
||||
- git clone $TEST_SCRIPT_REPOSITORY
|
||||
- cd auto_test_script
|
||||
- git checkout ${CI_COMMIT_REF_NAME} || echo "Using default branch..."
|
||||
# assign unit test cases
|
||||
- python CIAssignTestCases.py -t $IDF_PATH/components/idf_test/unit_test -c $IDF_PATH/.gitlab-ci.yml -b $IDF_PATH/test_bins
|
||||
# assgin integration test cases
|
||||
- python CIAssignTestCases.py -t $IDF_PATH/components/idf_test/integration_test -c $IDF_PATH/.gitlab-ci.yml -b $IDF_PATH/test_bins
|
||||
|
||||
.test_template: &test_template
|
||||
before_script:
|
||||
- echo "Skip cloning submodule here"
|
||||
stage: test
|
||||
when: on_success
|
||||
only:
|
||||
- master
|
||||
- /^release\/v/
|
||||
- /^v\d+\.\d+(\.\d+)?($|-)/
|
||||
- triggers
|
||||
allow_failure: true
|
||||
dependencies:
|
||||
- assign_test
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $LOG_PATH
|
||||
expire_in: 6 mos
|
||||
variables:
|
||||
# set git strategy to fetch so we can get esptool without update submodule
|
||||
GIT_STRATEGY: fetch
|
||||
LOCAL_ENV_CONFIG_PATH: "$CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32_IDF"
|
||||
LOG_PATH: "$CI_PROJECT_DIR/$CI_COMMIT_SHA"
|
||||
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test/integration_test"
|
||||
MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/components/idf_test/ModuleDefinition.yml"
|
||||
CONFIG_FILE: "$CI_PROJECT_DIR/components/idf_test/integration_test/CIConfigs/$CI_JOB_NAME.yml"
|
||||
script:
|
||||
# first test if config file exists, if not exist, exit 0
|
||||
- test -e $CONFIG_FILE || exit 0
|
||||
# remove artifacts from the 'unit_test' stage
|
||||
- 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 $TEST_ENV_CONFIG_REPOSITORY
|
||||
# clone test bench
|
||||
- git clone $TEST_SCRIPT_REPOSITORY
|
||||
- cd auto_test_script
|
||||
- git checkout ${CI_COMMIT_REF_NAME} || echo "Using default branch..."
|
||||
# run test
|
||||
- python CIRunner.py -l "$LOG_PATH/$CI_JOB_NAME" -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH -m $MODULE_UPDATE_FILE
|
||||
|
||||
# template for unit test jobs
|
||||
.unit_test_template: &unit_test_template
|
||||
<<: *test_template
|
||||
allow_failure: false
|
||||
stage: unit_test
|
||||
variables:
|
||||
GIT_STRATEGY: fetch
|
||||
LOCAL_ENV_CONFIG_PATH: "$CI_PROJECT_DIR/ci-test-runner-configs/$CI_RUNNER_DESCRIPTION/ESP32_IDF"
|
||||
LOG_PATH: "$CI_PROJECT_DIR/$CI_COMMIT_SHA"
|
||||
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test/unit_test"
|
||||
MODULE_UPDATE_FILE: "$CI_PROJECT_DIR/components/idf_test/ModuleDefinition.yml"
|
||||
CONFIG_FILE: "$CI_PROJECT_DIR/components/idf_test/unit_test/CIConfigs/$CI_JOB_NAME.yml"
|
||||
|
||||
nvs_compatible_test:
|
||||
<<: *test_template
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $LOG_PATH
|
||||
- nvs_wifi.bin
|
||||
expire_in: 6 mos
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- NVS_Compatible
|
||||
script:
|
||||
# remove artifacts from the 'unit_test' stage
|
||||
- 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 $TEST_ENV_CONFIG_REPOSITORY
|
||||
# clone test bench
|
||||
- git clone $TEST_SCRIPT_REPOSITORY
|
||||
- cd auto_test_script
|
||||
- git checkout ${CI_COMMIT_REF_NAME} || echo "Using default branch..."
|
||||
# prepare nvs bins
|
||||
- ./Tools/prepare_nvs_bin.sh
|
||||
# run test
|
||||
- python CIRunner.py -l "$LOG_PATH/$CI_JOB_NAME" -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH -m $MODULE_UPDATE_FILE
|
||||
|
||||
UT_001_01:
|
||||
<<: *unit_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_1
|
||||
|
||||
UT_001_02:
|
||||
<<: *unit_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_1
|
||||
|
||||
UT_001_03:
|
||||
<<: *unit_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_1
|
||||
|
||||
UT_001_04:
|
||||
<<: *unit_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_1
|
||||
|
||||
IT_001_01:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
|
||||
IT_001_02:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
|
||||
IT_001_03:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
|
||||
IT_001_04:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
|
||||
IT_001_05:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
|
||||
IT_001_06:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
|
||||
IT_001_07:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
|
||||
IT_001_08:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
|
||||
IT_002_01:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_2
|
||||
|
||||
IT_003_01:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_1
|
||||
|
||||
IT_003_02:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_1
|
||||
|
||||
IT_003_03:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_1
|
||||
|
||||
IT_004_01:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_APC
|
||||
|
||||
IT_005_01:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_WEP
|
||||
|
||||
IT_006_01:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T3_PhyMode
|
||||
|
||||
IT_007_01:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_PhyMode
|
||||
|
||||
IT_008_01:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_PhyMode
|
||||
|
||||
IT_501_01:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- stress_test
|
||||
|
||||
IT_501_02:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- stress_test
|
||||
|
||||
IT_501_03:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- stress_test
|
||||
|
||||
IT_502_01:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_1
|
||||
- stress_test
|
||||
|
||||
IT_502_02:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_1
|
||||
- stress_test
|
||||
|
||||
IT_503_01:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T5_1
|
||||
- stress_test
|
||||
|
||||
IT_503_02:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T5_1
|
||||
- stress_test
|
||||
|
||||
IT_503_03:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T5_1
|
||||
- stress_test
|
||||
|
||||
24
.gitmodules
vendored
24
.gitmodules
vendored
@@ -1,9 +1,31 @@
|
||||
[submodule "components/esp32/lib"]
|
||||
path = components/esp32/lib
|
||||
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
|
||||
|
||||
[submodule "components/aws_iot/aws-iot-device-sdk-embedded-C"]
|
||||
path = components/aws_iot/aws-iot-device-sdk-embedded-C
|
||||
url = https://github.com/espressif/aws-iot-device-sdk-embedded-C.git
|
||||
|
||||
[submodule "components/nghttp/nghttp2"]
|
||||
path = components/nghttp/nghttp2
|
||||
url = https://github.com/nghttp2/nghttp2.git
|
||||
|
||||
[submodule "components/libsodium/libsodium"]
|
||||
path = components/libsodium/libsodium
|
||||
url = https://github.com/jedisct1/libsodium.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,18 @@ 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 [Contributor Agreement](docs/contributor-agreement.rst). 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 :doc:`contributor-agreement`. You will be prompted for this automatically as part of the Pull Request process.
|
||||
|
||||
Related Documents
|
||||
-----------------
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
style-guide
|
||||
documenting-code
|
||||
../api-reference/template
|
||||
contributor-agreement
|
||||
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
|
||||
|
||||
81
README.md
81
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/get-started/windows-setup.html)
|
||||
* [Mac OS Setup Guide](http://esp-idf.readthedocs.io/en/latest/get-started/macos-setup.html)
|
||||
* [Linux Setup Guide](http://esp-idf.readthedocs.io/en/latest/get-started/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 uses the [idf_monitor tool](http://esp-idf.readthedocs.io/en/latest/get-started/idf-monitor.html) to display serial output from the ESP32. idf_monitor also has a range of features to decode crash output and interact with the device. [Check the documentation page for details](http://esp-idf.readthedocs.io/en/latest/get-started/idf-monitor.html).
|
||||
|
||||
Exit the monitor 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,13 +69,23 @@ 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.
|
||||
|
||||
A single ESP32's flash can contain multiple apps, as well as many different kinds of data (calibration data, filesystems, parameter storage, etc). For this reason a partition table is flashed to offset 0x4000 in the flash.
|
||||
A single ESP32's flash can contain multiple apps, as well as many different kinds of data (calibration data, filesystems, parameter storage, etc). For this reason a partition table is flashed to offset 0x8000 in the flash.
|
||||
|
||||
Each entry in the partition table has a name (label), type (app, data, or something else), subtype and the offset in flash where the partition is loaded.
|
||||
|
||||
@@ -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/contribute/index.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.)
|
||||
|
||||
539
components/app_update/esp_ota_ops.c
Normal file
539
components/app_update/esp_ota_ops.c
Normal file
@@ -0,0 +1,539 @@
|
||||
// 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 "soc/dport_reg.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;
|
||||
const esp_partition_t *part;
|
||||
uint32_t erased_size;
|
||||
uint32_t wrote_size;
|
||||
uint8_t partial_bytes;
|
||||
uint8_t partial_data[16];
|
||||
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";
|
||||
|
||||
/* Return true if this is an OTA app partition */
|
||||
static bool is_ota_partition(const esp_partition_t *p)
|
||||
{
|
||||
return (p != NULL
|
||||
&& p->type == ESP_PARTITION_TYPE_APP
|
||||
&& p->subtype >= ESP_PARTITION_SUBTYPE_APP_OTA_0
|
||||
&& p->subtype < ESP_PARTITION_SUBTYPE_APP_OTA_MAX);
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_begin(const esp_partition_t *partition, size_t image_size, esp_ota_handle_t *out_handle)
|
||||
{
|
||||
ota_ops_entry_t *new_entry;
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if ((partition == NULL) || (out_handle == NULL)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
partition = esp_partition_verify(partition);
|
||||
if (partition == NULL) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (!is_ota_partition(partition)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (partition == esp_ota_get_running_partition()) {
|
||||
return ESP_ERR_OTA_PARTITION_CONFLICT;
|
||||
}
|
||||
|
||||
// If input image size is 0 or OTA_SIZE_UNKNOWN, erase entire 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) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
new_entry = (ota_ops_entry_t *) calloc(sizeof(ota_ops_entry_t), 1);
|
||||
if (new_entry == NULL) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
new_entry->part = partition;
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (it->partial_bytes > 0) {
|
||||
/* 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;
|
||||
}
|
||||
|
||||
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_INVALID_ARG;
|
||||
}
|
||||
|
||||
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, 1, find_partition);
|
||||
} else {
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 0, 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const esp_partition_t* esp_ota_get_running_partition(void)
|
||||
{
|
||||
/* Find the flash address of this exact function. By definition that is part
|
||||
of the currently running firmware. Then find the enclosing partition. */
|
||||
|
||||
size_t phys_offs = spi_flash_cache2phys(esp_ota_get_running_partition);
|
||||
|
||||
assert (phys_offs != SPI_FLASH_CACHE2PHYS_FAIL); /* indicates cache2phys lookup is buggy */
|
||||
|
||||
esp_partition_iterator_t it = esp_partition_find(ESP_PARTITION_TYPE_APP,
|
||||
ESP_PARTITION_SUBTYPE_ANY,
|
||||
NULL);
|
||||
assert(it != NULL); /* has to be at least one app partition */
|
||||
|
||||
while (it != NULL) {
|
||||
const esp_partition_t *p = esp_partition_get(it);
|
||||
if (p->address <= phys_offs && p->address + p->size > phys_offs) {
|
||||
esp_partition_iterator_release(it);
|
||||
return p;
|
||||
}
|
||||
it = esp_partition_next(it);
|
||||
}
|
||||
|
||||
abort(); /* Partition table is invalid or corrupt */
|
||||
}
|
||||
|
||||
|
||||
const esp_partition_t* esp_ota_get_next_update_partition(const esp_partition_t *start_from)
|
||||
{
|
||||
const esp_partition_t *default_ota = NULL;
|
||||
bool next_is_result = false;
|
||||
if (start_from == NULL) {
|
||||
start_from = esp_ota_get_running_partition();
|
||||
} else {
|
||||
start_from = esp_partition_verify(start_from);
|
||||
}
|
||||
assert (start_from != NULL);
|
||||
/* at this point, 'start_from' points to actual partition table data in flash */
|
||||
|
||||
|
||||
/* Two possibilities: either we want the OTA partition immediately after the current running OTA partition, or we
|
||||
want the first OTA partition in the table (for the case when the last OTA partition is the running partition, or
|
||||
if the current running partition is not OTA.)
|
||||
|
||||
This loop iterates subtypes instead of using esp_partition_find, so we
|
||||
get all OTA partitions in a known order (low slot to high slot).
|
||||
*/
|
||||
|
||||
for (esp_partition_subtype_t t = ESP_PARTITION_SUBTYPE_APP_OTA_0;
|
||||
t != ESP_PARTITION_SUBTYPE_APP_OTA_MAX;
|
||||
t++) {
|
||||
const esp_partition_t *p = esp_partition_find_first(ESP_PARTITION_TYPE_APP, t, NULL);
|
||||
if (p == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (default_ota == NULL) {
|
||||
/* Default to first OTA partition we find,
|
||||
will be used if nothing else matches */
|
||||
default_ota = p;
|
||||
}
|
||||
|
||||
if (p == start_from) {
|
||||
/* Next OTA partition is the one to use */
|
||||
next_is_result = true;
|
||||
}
|
||||
else if (next_is_result) {
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
return default_ota;
|
||||
|
||||
}
|
||||
168
components/app_update/include/esp_ota_ops.h
Executable file
168
components/app_update/include/esp_ota_ops.h
Executable file
@@ -0,0 +1,168 @@
|
||||
// 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 /*!< Used for esp_ota_begin() if new image size is unknown */
|
||||
|
||||
#define ESP_ERR_OTA_BASE 0x1500 /*!< Base error code for ota_ops api */
|
||||
#define ESP_ERR_OTA_PARTITION_CONFLICT (ESP_ERR_OTA_BASE + 0x01) /*!< Error if request was to write or erase the current running partition */
|
||||
#define ESP_ERR_OTA_SELECT_INFO_INVALID (ESP_ERR_OTA_BASE + 0x02) /*!< Error if OTA data partition contains invalid content */
|
||||
#define ESP_ERR_OTA_VALIDATE_FAILED (ESP_ERR_OTA_BASE + 0x03) /*!< Error if OTA app image is invalid */
|
||||
|
||||
/**
|
||||
* @brief Opaque handle for an application OTA update
|
||||
*
|
||||
* esp_ota_begin() returns a handle which is then used for subsequent
|
||||
* calls to esp_ota_write() and esp_ota_end().
|
||||
*/
|
||||
typedef uint32_t esp_ota_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Commence an OTA update writing to the specified partition.
|
||||
|
||||
* The specified partition is erased to the specified image size.
|
||||
*
|
||||
* If image size is not yet known, pass OTA_SIZE_UNKNOWN which will
|
||||
* cause the entire partition to be erased.
|
||||
*
|
||||
* On success, this function allocates memory that remains in use
|
||||
* until esp_ota_end() is called with the returned handle.
|
||||
*
|
||||
* @param partition Pointer to info for partition which will receive the OTA update. Required.
|
||||
* @param image_size Size of new OTA app image. Partition will be erased in order to receive this size of image. If 0 or OTA_SIZE_UNKNOWN, the entire partition is erased.
|
||||
* @param out_handle On success, returns a handle which should be used for subsequent esp_ota_write() and esp_ota_end() calls.
|
||||
|
||||
* @return
|
||||
* - ESP_OK: OTA operation commenced successfully.
|
||||
* - ESP_ERR_INVALID_ARG: partition or out_handle arguments were NULL, or partition doesn't point to an OTA app partition.
|
||||
* - ESP_ERR_NO_MEM: Cannot allocate memory for OTA operation.
|
||||
* - ESP_ERR_OTA_PARTITION_CONFLICT: Partition holds the currently running firmware, cannot update in place.
|
||||
* - ESP_ERR_NOT_FOUND: Partition argument not found in partition table.
|
||||
* - ESP_ERR_OTA_SELECT_INFO_INVALID: The OTA data partition contains invalid data.
|
||||
* - ESP_ERR_INVALID_SIZE: Partition doesn't fit in configured flash size.
|
||||
* - ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash write failed.
|
||||
*/
|
||||
esp_err_t esp_ota_begin(const esp_partition_t* partition, size_t image_size, esp_ota_handle_t* out_handle);
|
||||
|
||||
/**
|
||||
* @brief Write OTA update data to partition
|
||||
*
|
||||
* This function can be called multiple times as
|
||||
* data is received during the OTA operation. Data is written
|
||||
* sequentially to the partition.
|
||||
*
|
||||
* @param handle Handle obtained from esp_ota_begin
|
||||
* @param data Data buffer to write
|
||||
* @param size Size of data buffer in bytes.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: Data was written to flash successfully.
|
||||
* - ESP_ERR_INVALID_ARG: handle is invalid.
|
||||
* - ESP_ERR_OTA_VALIDATE_FAILED: First byte of image contains invalid app image magic byte.
|
||||
* - ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash write failed.
|
||||
* - ESP_ERR_OTA_SELECT_INFO_INVALID: OTA data partition has invalid contents
|
||||
*/
|
||||
esp_err_t esp_ota_write(esp_ota_handle_t handle, const void* data, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Finish OTA update and validate newly written app image.
|
||||
*
|
||||
* @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 Configure OTA data for a new boot partition
|
||||
*
|
||||
* @note If this function returns ESP_OK, calling esp_restart() will boot the newly configured app partition.
|
||||
*
|
||||
* @param partition Pointer to info for partition containing app image to boot.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: OTA data updated, next reboot will use specified partition.
|
||||
* - ESP_ERR_INVALID_ARG: partition argument was NULL or didn't point to a valid OTA partition of type "app".
|
||||
* - ESP_ERR_OTA_VALIDATE_FAILED: Partition contained invalid app image. Also returned if secure boot is enabled and signature validation failed.
|
||||
* - ESP_ERR_NOT_FOUND: OTA data partition not found.
|
||||
* - ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash erase or write failed.
|
||||
*/
|
||||
esp_err_t esp_ota_set_boot_partition(const esp_partition_t* partition);
|
||||
|
||||
/**
|
||||
* @brief Get partition info of currently configured boot app
|
||||
*
|
||||
* If esp_ota_set_boot_partition() has been called, the partition which was set by that function will be returned.
|
||||
*
|
||||
* If esp_ota_set_boot_partition() has not been called, the result is
|
||||
* equivalent to esp_ota_get_running_partition().
|
||||
*
|
||||
* @return Pointer to info for partition structure, or NULL if no partition is found or flash read operation failed. Returned pointer is valid for the lifetime of the application.
|
||||
*/
|
||||
const esp_partition_t* esp_ota_get_boot_partition(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get partition info of currently running app
|
||||
*
|
||||
* This function is different to esp_ota_get_boot_partition() in that
|
||||
* it ignores any change of selected boot partition caused by
|
||||
* esp_ota_set_boot_partition(). Only the app whose code is currently
|
||||
* running will have its partition information returned.
|
||||
*
|
||||
* @return Pointer to info for partition structure, or NULL if no partition is found or flash read operation failed. Returned pointer is valid for the lifetime of the application.
|
||||
*/
|
||||
const esp_partition_t* esp_ota_get_running_partition(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return the next OTA app partition which should be written with a new firmware.
|
||||
*
|
||||
* Call this function to find an OTA app partition which can be passed to esp_ota_begin().
|
||||
*
|
||||
* Finds next partition round-robin, starting from the current running partition.
|
||||
*
|
||||
* @param start_from If set, treat this partition info as describing the current running partition. Can be NULL, in which case esp_ota_get_running_partition() is used to find the currently running partition. The result of this function is never the same as this argument.
|
||||
*
|
||||
* @return Pointer to info for partition which should be updated next. NULL result indicates invalid OTA data partition, or that no eligible OTA app slot partition was found.
|
||||
*
|
||||
*/
|
||||
const esp_partition_t* esp_ota_get_next_update_partition(const esp_partition_t *start_from);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OTA_OPS_H */
|
||||
5
components/app_update/test/component.mk
Normal file
5
components/app_update/test/component.mk
Normal file
@@ -0,0 +1,5 @@
|
||||
#
|
||||
#Component Makefile
|
||||
#
|
||||
|
||||
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive
|
||||
86
components/app_update/test/test_ota_ops.c
Normal file
86
components/app_update/test/test_ota_ops.c
Normal file
@@ -0,0 +1,86 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <freertos/semphr.h>
|
||||
|
||||
#include <unity.h>
|
||||
#include <test_utils.h>
|
||||
#include <esp_ota_ops.h>
|
||||
|
||||
|
||||
/* These OTA tests currently don't assume an OTA partition exists
|
||||
on the device, so they're a bit limited
|
||||
*/
|
||||
|
||||
TEST_CASE("esp_ota_begin() verifies arguments", "[ota]")
|
||||
{
|
||||
const esp_partition_t *running = esp_ota_get_running_partition();
|
||||
esp_partition_t partition;
|
||||
static esp_ota_handle_t handle = 0;
|
||||
|
||||
if (handle != 0) { /* clean up from any previous test */
|
||||
esp_ota_end(handle);
|
||||
handle = 0;
|
||||
}
|
||||
|
||||
/* running partition & configured boot partition are same */
|
||||
TEST_ASSERT_NOT_NULL(running);
|
||||
|
||||
/* trying to 'begin' on running partition fails */
|
||||
TEST_ASSERT_NOT_EQUAL(ESP_OK, esp_ota_begin(running, OTA_SIZE_UNKNOWN, &handle));
|
||||
TEST_ASSERT_EQUAL(0, handle);
|
||||
|
||||
memcpy(&partition, running, sizeof(esp_partition_t));
|
||||
partition.address--;
|
||||
|
||||
/* non existent partition fails */
|
||||
TEST_ASSERT_EQUAL_HEX(ESP_ERR_NOT_FOUND, esp_ota_begin(&partition, OTA_SIZE_UNKNOWN, &handle));
|
||||
TEST_ASSERT_EQUAL(0, handle);
|
||||
}
|
||||
|
||||
TEST_CASE("esp_ota_get_next_update_partition logic", "[ota]")
|
||||
{
|
||||
const esp_partition_t *running = esp_ota_get_running_partition();
|
||||
const esp_partition_t *factory = esp_partition_find_first(ESP_PARTITION_TYPE_APP,
|
||||
ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);
|
||||
const esp_partition_t *ota_0 = esp_partition_find_first(ESP_PARTITION_TYPE_APP,
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_0, NULL);
|
||||
const esp_partition_t *ota_1 = esp_partition_find_first(ESP_PARTITION_TYPE_APP,
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_1, NULL);
|
||||
const esp_partition_t *ota_2 = esp_partition_find_first(ESP_PARTITION_TYPE_APP,
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_2, NULL);
|
||||
|
||||
TEST_ASSERT_NOT_NULL(running);
|
||||
TEST_ASSERT_NOT_NULL(factory);
|
||||
TEST_ASSERT_NOT_NULL(ota_0);
|
||||
TEST_ASSERT_NOT_NULL(ota_1);
|
||||
TEST_ASSERT_NULL(ota_2); /* this partition shouldn't exist in test partition table */
|
||||
|
||||
TEST_ASSERT_EQUAL_PTR(factory, running); /* this may not be true if/when we get OTA tests that do OTA updates */
|
||||
|
||||
/* (The test steps verify subtypes before verifying pointer equality, because the failure messages are more readable
|
||||
this way.)
|
||||
*/
|
||||
|
||||
/* Factory app OTA updates OTA 0 slot */
|
||||
const esp_partition_t *p = esp_ota_get_next_update_partition(NULL);
|
||||
TEST_ASSERT_EQUAL_HEX8(ESP_PARTITION_SUBTYPE_APP_OTA_0, p->subtype);
|
||||
TEST_ASSERT_EQUAL_PTR(ota_0, p);
|
||||
|
||||
p = esp_ota_get_next_update_partition(factory);
|
||||
TEST_ASSERT_EQUAL_HEX8(ESP_PARTITION_SUBTYPE_APP_OTA_0, p->subtype);
|
||||
TEST_ASSERT_EQUAL_PTR(ota_0, p);
|
||||
|
||||
|
||||
/* OTA slot 0 updates OTA slot 1 */
|
||||
p = esp_ota_get_next_update_partition(ota_0);
|
||||
TEST_ASSERT_EQUAL_HEX8(ESP_PARTITION_SUBTYPE_APP_OTA_1, p->subtype);
|
||||
TEST_ASSERT_EQUAL_PTR(ota_1, p);
|
||||
/* OTA slot 1 updates OTA slot 0 */
|
||||
p = esp_ota_get_next_update_partition(ota_1);
|
||||
TEST_ASSERT_EQUAL_HEX8(ESP_PARTITION_SUBTYPE_APP_OTA_0, p->subtype);;
|
||||
TEST_ASSERT_EQUAL_PTR(ota_0, p);
|
||||
}
|
||||
|
||||
32
components/aws_iot/Kconfig
Normal file
32
components/aws_iot/Kconfig
Normal file
@@ -0,0 +1,32 @@
|
||||
menuconfig AWS_IOT_SDK
|
||||
bool "Amazon Web Services IoT Platform"
|
||||
help
|
||||
Select this option to enable support for the AWS IoT platform,
|
||||
via the esp-idf component for the AWS IoT Device C SDK.
|
||||
|
||||
config AWS_IOT_MQTT_HOST
|
||||
string "AWS IoT Endpoint Hostname"
|
||||
depends on AWS_IOT_SDK
|
||||
default ""
|
||||
help
|
||||
Default endpoint host name to connect to AWS IoT MQTT/S gateway
|
||||
|
||||
This is the custom endpoint hostname and is specific to an AWS
|
||||
IoT account. You can find it by logging into your AWS IoT
|
||||
Console and clicking the Settings button. The endpoint hostname
|
||||
is shown under the "Custom Endpoint" heading on this page.
|
||||
|
||||
If you need per-device hostnames for different regions or
|
||||
accounts, you can override the default hostname in your app.
|
||||
|
||||
config AWS_IOT_MQTT_PORT
|
||||
int "AWS IoT MQTT Port"
|
||||
depends on AWS_IOT_SDK
|
||||
default 8883
|
||||
range 0 65535
|
||||
help
|
||||
Default port number to connect to AWS IoT MQTT/S gateway
|
||||
|
||||
If you need per-device port numbers for different regions, you can
|
||||
override the default port number in your app.
|
||||
|
||||
1
components/aws_iot/aws-iot-device-sdk-embedded-C
Submodule
1
components/aws_iot/aws-iot-device-sdk-embedded-C
Submodule
Submodule components/aws_iot/aws-iot-device-sdk-embedded-C added at 7132505b00
20
components/aws_iot/component.mk
Normal file
20
components/aws_iot/component.mk
Normal file
@@ -0,0 +1,20 @@
|
||||
#
|
||||
# Component Makefile
|
||||
#
|
||||
|
||||
ifdef CONFIG_AWS_IOT_SDK
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS := include aws-iot-device-sdk-embedded-C/include
|
||||
|
||||
COMPONENT_SRCDIRS := aws-iot-device-sdk-embedded-C/src port
|
||||
|
||||
# Check the submodule is initialised
|
||||
COMPONENT_SUBMODULES := aws-iot-device-sdk-embedded-C
|
||||
|
||||
|
||||
else
|
||||
# Disable AWS IoT support
|
||||
COMPONENT_ADD_INCLUDEDIRS :=
|
||||
COMPONENT_ADD_LDFLAGS :=
|
||||
COMPONENT_SRCDIRS :=
|
||||
endif
|
||||
60
components/aws_iot/include/aws_iot_config.h
Normal file
60
components/aws_iot/include/aws_iot_config.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License").
|
||||
* You may not use this file except in compliance with the License.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file aws_iot_config.h
|
||||
* @brief AWS IoT specific configuration file
|
||||
*/
|
||||
|
||||
#ifndef _AWS_IOT_CONFIG_H_
|
||||
#define _AWS_IOT_CONFIG_H_
|
||||
|
||||
#include "aws_iot_log.h"
|
||||
|
||||
// This configuration macro needs to be available globally to enable threading
|
||||
#define _ENABLE_THREAD_SUPPORT_
|
||||
|
||||
// These values are defined in the menuconfig of the AWS IoT component.
|
||||
// However, you can override these constants from your own code.
|
||||
#define AWS_IOT_MQTT_HOST CONFIG_AWS_IOT_MQTT_HOST ///< Customer specific MQTT HOST. The same will be used for Thing Shadow
|
||||
#define AWS_IOT_MQTT_PORT CONFIG_AWS_IOT_MQTT_PORT ///< default port for MQTT/S
|
||||
|
||||
// These values are defaults and are used for ShadowConnectParametersDefault.
|
||||
// You should override them from your own code.
|
||||
#define AWS_IOT_MQTT_CLIENT_ID "ESP32" ///< MQTT client ID should be unique for every device
|
||||
#define AWS_IOT_MY_THING_NAME "ESP32" ///< Thing Name of the Shadow this device is associated with
|
||||
|
||||
// MQTT PubSub
|
||||
#define AWS_IOT_MQTT_TX_BUF_LEN 512 ///< Any time a message is sent out through the MQTT layer. The message is copied into this buffer anytime a publish is done. This will also be used in the case of Thing Shadow
|
||||
#define AWS_IOT_MQTT_RX_BUF_LEN 512 ///< Any message that comes into the device should be less than this buffer size. If a received message is bigger than this buffer size the message will be dropped.
|
||||
#define AWS_IOT_MQTT_NUM_SUBSCRIBE_HANDLERS 5 ///< Maximum number of topic filters the MQTT client can handle at any given time. This should be increased appropriately when using Thing Shadow
|
||||
|
||||
// Thing Shadow specific configs
|
||||
#define SHADOW_MAX_SIZE_OF_RX_BUFFER (AWS_IOT_MQTT_RX_BUF_LEN + 1) ///< Maximum size of the SHADOW buffer to store the received Shadow message
|
||||
#define MAX_SIZE_OF_UNIQUE_CLIENT_ID_BYTES 80 ///< Maximum size of the Unique Client Id. For More info on the Client Id refer \ref response "Acknowledgments"
|
||||
#define MAX_SIZE_CLIENT_ID_WITH_SEQUENCE (MAX_SIZE_OF_UNIQUE_CLIENT_ID_BYTES + 10) ///< This is size of the extra sequence number that will be appended to the Unique client Id
|
||||
#define MAX_SIZE_CLIENT_TOKEN_CLIENT_SEQUENCE (MAX_SIZE_CLIENT_ID_WITH_SEQUENCE + 20) ///< This is size of the the total clientToken key and value pair in the JSON
|
||||
#define MAX_ACKS_TO_COMEIN_AT_ANY_GIVEN_TIME 10 ///< At Any given time we will wait for this many responses. This will correlate to the rate at which the shadow actions are requested
|
||||
#define MAX_THINGNAME_HANDLED_AT_ANY_GIVEN_TIME 10 ///< We could perform shadow action on any thing Name and this is maximum Thing Names we can act on at any given time
|
||||
#define MAX_JSON_TOKEN_EXPECTED 120 ///< These are the max tokens that is expected to be in the Shadow JSON document. Include the metadata that gets published
|
||||
#define MAX_SHADOW_TOPIC_LENGTH_WITHOUT_THINGNAME 60 ///< All shadow actions have to be published or subscribed to a topic which is of the formablogt $aws/things/{thingName}/shadow/update/accepted. This refers to the size of the topic without the Thing Name
|
||||
#define MAX_SIZE_OF_THING_NAME 20 ///< The Thing Name should not be bigger than this value. Modify this if the Thing Name needs to be bigger
|
||||
#define MAX_SHADOW_TOPIC_LENGTH_BYTES (MAX_SHADOW_TOPIC_LENGTH_WITHOUT_THINGNAME + MAX_SIZE_OF_THING_NAME) ///< This size includes the length of topic with Thing Name
|
||||
|
||||
// Auto Reconnect specific config
|
||||
#define AWS_IOT_MQTT_MIN_RECONNECT_WAIT_INTERVAL 1000 ///< Minimum time before the First reconnect attempt is made as part of the exponential back-off algorithm
|
||||
#define AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL 128000 ///< Maximum time interval after which exponential back-off will stop attempting to reconnect.
|
||||
|
||||
#endif /* _AWS_IOT_CONFIG_H_ */
|
||||
44
components/aws_iot/include/aws_iot_log.h
Normal file
44
components/aws_iot/include/aws_iot_log.h
Normal file
@@ -0,0 +1,44 @@
|
||||
// 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.
|
||||
#pragma once
|
||||
|
||||
/* (these two headers aren't used here, but AWS IoT SDK code relies on them
|
||||
being included from here...) */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
|
||||
/* This is a stub replacement for the aws_iot_log.h header in the AWS IoT SDK,
|
||||
which redirects their logging framework into the esp-idf logging framework.
|
||||
|
||||
The current (2.1.1) upstream AWS IoT SDK doesn't allow this as some of its
|
||||
headers include aws_iot_log.h, but our modified fork does.
|
||||
*/
|
||||
|
||||
// redefine the AWS IoT log functions to call into the IDF log layer
|
||||
#define IOT_DEBUG(format, ...) ESP_LOGD("aws_iot", format, ##__VA_ARGS__)
|
||||
#define IOT_INFO(format, ...) ESP_LOGI("aws_iot", format, ##__VA_ARGS__)
|
||||
#define IOT_WARN(format, ...) ESP_LOGW("aws_iot", format, ##__VA_ARGS__)
|
||||
#define IOT_ERROR(format, ...) ESP_LOGE("aws_iot", format, ##__VA_ARGS__)
|
||||
|
||||
/* Function tracing macros used in AWS IoT SDK,
|
||||
mapped to "verbose" level output
|
||||
*/
|
||||
#define FUNC_ENTRY ESP_LOGV("aws_iot", "FUNC_ENTRY: %s L#%d \n", __func__, __LINE__)
|
||||
#define FUNC_EXIT_RC(x) \
|
||||
do { \
|
||||
ESP_LOGV("aws_iot", "FUNC_EXIT: %s L#%d Return Code : %d \n", __func__, __LINE__, x); \
|
||||
return x; \
|
||||
} while(0)
|
||||
64
components/aws_iot/include/network_platform.h
Normal file
64
components/aws_iot/include/network_platform.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* Additions Copyright 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.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file 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 IOTSDKC_NETWORK_MBEDTLS_PLATFORM_H_H
|
||||
|
||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||
#include "mbedtls/config.h"
|
||||
#else
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#include "mbedtls/platform.h"
|
||||
#include "mbedtls/net.h"
|
||||
#include "mbedtls/ssl.h"
|
||||
#include "mbedtls/entropy.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/certs.h"
|
||||
#include "mbedtls/x509.h"
|
||||
#include "mbedtls/error.h"
|
||||
#include "mbedtls/debug.h"
|
||||
#include "mbedtls/timing.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief TLS Connection Parameters
|
||||
*
|
||||
* Defines a type containing TLS specific parameters to be passed down to the
|
||||
* TLS networking layer to create a TLS secured socket.
|
||||
*/
|
||||
typedef struct _TLSDataParams {
|
||||
mbedtls_entropy_context entropy;
|
||||
mbedtls_ctr_drbg_context ctr_drbg;
|
||||
mbedtls_ssl_context ssl;
|
||||
mbedtls_ssl_config conf;
|
||||
uint32_t flags;
|
||||
mbedtls_x509_crt cacert;
|
||||
mbedtls_x509_crt clicert;
|
||||
mbedtls_pk_context pkey;
|
||||
mbedtls_net_context server_fd;
|
||||
}TLSDataParams;
|
||||
|
||||
#define IOTSDKC_NETWORK_MBEDTLS_PLATFORM_H_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //IOTSDKC_NETWORK_MBEDTLS_PLATFORM_H_H
|
||||
45
components/aws_iot/include/threads_platform.h
Normal file
45
components/aws_iot/include/threads_platform.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* Additions Copyright 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.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file 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 "threads_interface.h"
|
||||
|
||||
#ifndef AWS_IOTSDK_THREADS_PLATFORM_H
|
||||
#define AWS_IOTSDK_THREADS_PLATFORM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
/**
|
||||
* @brief Mutex Type
|
||||
*
|
||||
* definition of the Mutex struct. Platform specific
|
||||
*
|
||||
*/
|
||||
struct _IoT_Mutex_t {
|
||||
SemaphoreHandle_t mutex;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AWS_IOTSDK_THREADS_PLATFORM_H */
|
||||
|
||||
|
||||
40
components/aws_iot/include/timer_platform.h
Normal file
40
components/aws_iot/include/timer_platform.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* Additions Copyright 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.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file 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 AWS_IOT_PLATFORM_H
|
||||
#define AWS_IOT_PLATFORM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include "timer_interface.h"
|
||||
|
||||
/**
|
||||
* definition of the Timer struct. Platform specific
|
||||
*/
|
||||
struct Timer {
|
||||
uint32_t start_ticks;
|
||||
uint32_t timeout_ticks;
|
||||
uint32_t last_polled_ticks;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AWS_IOT_PLATFORM_H */
|
||||
408
components/aws_iot/port/network_mbedtls_wrapper.c
Normal file
408
components/aws_iot/port/network_mbedtls_wrapper.c
Normal file
@@ -0,0 +1,408 @@
|
||||
/*
|
||||
* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* Additions Copyright 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.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file 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 <sys/param.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <timer_platform.h>
|
||||
#include <network_interface.h>
|
||||
|
||||
#include "aws_iot_config.h"
|
||||
#include "aws_iot_error.h"
|
||||
#include "network_interface.h"
|
||||
#include "network_platform.h"
|
||||
|
||||
#include "mbedtls/esp_debug.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "esp_vfs.h"
|
||||
|
||||
static const char *TAG = "aws_iot";
|
||||
|
||||
/* This is the value used for ssl read timeout */
|
||||
#define IOT_SSL_READ_TIMEOUT 10
|
||||
|
||||
/*
|
||||
* This is a function to do further verification if needed on the cert received.
|
||||
*
|
||||
* Currently used to print debug-level information about each cert.
|
||||
*/
|
||||
static int _iot_tls_verify_cert(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags) {
|
||||
char buf[256];
|
||||
((void) data);
|
||||
|
||||
if (LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) {
|
||||
ESP_LOGD(TAG, "Verify requested for (Depth %d):", depth);
|
||||
mbedtls_x509_crt_info(buf, sizeof(buf) - 1, "", crt);
|
||||
ESP_LOGD(TAG, "%s", buf);
|
||||
|
||||
if((*flags) == 0) {
|
||||
ESP_LOGD(TAG, " This certificate has no flags");
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Verify result:%s", buf);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _iot_tls_set_connect_params(Network *pNetwork, const char *pRootCALocation, const char *pDeviceCertLocation,
|
||||
const char *pDevicePrivateKeyLocation, const char *pDestinationURL,
|
||||
uint16_t destinationPort, uint32_t timeout_ms, bool ServerVerificationFlag) {
|
||||
pNetwork->tlsConnectParams.DestinationPort = destinationPort;
|
||||
pNetwork->tlsConnectParams.pDestinationURL = pDestinationURL;
|
||||
pNetwork->tlsConnectParams.pDeviceCertLocation = pDeviceCertLocation;
|
||||
pNetwork->tlsConnectParams.pDevicePrivateKeyLocation = pDevicePrivateKeyLocation;
|
||||
pNetwork->tlsConnectParams.pRootCALocation = pRootCALocation;
|
||||
pNetwork->tlsConnectParams.timeout_ms = timeout_ms;
|
||||
pNetwork->tlsConnectParams.ServerVerificationFlag = ServerVerificationFlag;
|
||||
}
|
||||
|
||||
IoT_Error_t iot_tls_init(Network *pNetwork, const char *pRootCALocation, const char *pDeviceCertLocation,
|
||||
const char *pDevicePrivateKeyLocation, const char *pDestinationURL,
|
||||
uint16_t destinationPort, uint32_t timeout_ms, bool ServerVerificationFlag) {
|
||||
_iot_tls_set_connect_params(pNetwork, pRootCALocation, pDeviceCertLocation, pDevicePrivateKeyLocation,
|
||||
pDestinationURL, destinationPort, timeout_ms, ServerVerificationFlag);
|
||||
|
||||
pNetwork->connect = iot_tls_connect;
|
||||
pNetwork->read = iot_tls_read;
|
||||
pNetwork->write = iot_tls_write;
|
||||
pNetwork->disconnect = iot_tls_disconnect;
|
||||
pNetwork->isConnected = iot_tls_is_connected;
|
||||
pNetwork->destroy = iot_tls_destroy;
|
||||
|
||||
pNetwork->tlsDataParams.flags = 0;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
IoT_Error_t iot_tls_is_connected(Network *pNetwork) {
|
||||
/* Use this to add implementation which can check for physical layer disconnect */
|
||||
return NETWORK_PHYSICAL_LAYER_CONNECTED;
|
||||
}
|
||||
|
||||
IoT_Error_t iot_tls_connect(Network *pNetwork, TLSConnectParams *params) {
|
||||
int ret = SUCCESS;
|
||||
TLSDataParams *tlsDataParams = NULL;
|
||||
char portBuffer[6];
|
||||
char info_buf[256];
|
||||
|
||||
if(NULL == pNetwork) {
|
||||
return NULL_VALUE_ERROR;
|
||||
}
|
||||
|
||||
if(NULL != params) {
|
||||
_iot_tls_set_connect_params(pNetwork, params->pRootCALocation, params->pDeviceCertLocation,
|
||||
params->pDevicePrivateKeyLocation, params->pDestinationURL,
|
||||
params->DestinationPort, params->timeout_ms, params->ServerVerificationFlag);
|
||||
}
|
||||
|
||||
tlsDataParams = &(pNetwork->tlsDataParams);
|
||||
|
||||
mbedtls_net_init(&(tlsDataParams->server_fd));
|
||||
mbedtls_ssl_init(&(tlsDataParams->ssl));
|
||||
mbedtls_ssl_config_init(&(tlsDataParams->conf));
|
||||
|
||||
#ifdef CONFIG_MBEDTLS_DEBUG
|
||||
mbedtls_esp_enable_debug_log(&(tlsDataParams->conf), 4);
|
||||
#endif
|
||||
|
||||
mbedtls_ctr_drbg_init(&(tlsDataParams->ctr_drbg));
|
||||
mbedtls_x509_crt_init(&(tlsDataParams->cacert));
|
||||
mbedtls_x509_crt_init(&(tlsDataParams->clicert));
|
||||
mbedtls_pk_init(&(tlsDataParams->pkey));
|
||||
|
||||
ESP_LOGD(TAG, "Seeding the random number generator...");
|
||||
mbedtls_entropy_init(&(tlsDataParams->entropy));
|
||||
if((ret = mbedtls_ctr_drbg_seed(&(tlsDataParams->ctr_drbg), mbedtls_entropy_func, &(tlsDataParams->entropy),
|
||||
(const unsigned char *) TAG, strlen(TAG))) != 0) {
|
||||
ESP_LOGE(TAG, "failed! mbedtls_ctr_drbg_seed returned -0x%x", -ret);
|
||||
return NETWORK_MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
|
||||
}
|
||||
|
||||
/* Load root CA...
|
||||
|
||||
Certs/keys can be paths or they can be raw data. These use a
|
||||
very basic heuristic: if the cert starts with '/' then it's a
|
||||
path, if it's longer than this then it's raw cert data (PEM or DER,
|
||||
neither of which can start with a slash. */
|
||||
if (pNetwork->tlsConnectParams.pRootCALocation[0] == '/') {
|
||||
ESP_LOGD(TAG, "Loading CA root certificate from file ...");
|
||||
ret = mbedtls_x509_crt_parse_file(&(tlsDataParams->cacert), pNetwork->tlsConnectParams.pRootCALocation);
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Loading embedded CA root certificate ...");
|
||||
ret = mbedtls_x509_crt_parse(&(tlsDataParams->cacert), (const unsigned char *)pNetwork->tlsConnectParams.pRootCALocation,
|
||||
strlen(pNetwork->tlsConnectParams.pRootCALocation)+1);
|
||||
}
|
||||
|
||||
if(ret < 0) {
|
||||
ESP_LOGE(TAG, "failed! mbedtls_x509_crt_parse returned -0x%x while parsing root cert", -ret);
|
||||
return NETWORK_X509_ROOT_CRT_PARSE_ERROR;
|
||||
}
|
||||
ESP_LOGD(TAG, "ok (%d skipped)", ret);
|
||||
|
||||
/* Load client certificate... */
|
||||
if (pNetwork->tlsConnectParams.pDeviceCertLocation[0] == '/') {
|
||||
ESP_LOGD(TAG, "Loading client cert from file...");
|
||||
ret = mbedtls_x509_crt_parse_file(&(tlsDataParams->clicert),
|
||||
pNetwork->tlsConnectParams.pDeviceCertLocation);
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Loading embedded client certificate...");
|
||||
ret = mbedtls_x509_crt_parse(&(tlsDataParams->clicert),
|
||||
(const unsigned char *)pNetwork->tlsConnectParams.pDeviceCertLocation,
|
||||
strlen(pNetwork->tlsConnectParams.pDeviceCertLocation)+1);
|
||||
}
|
||||
if(ret != 0) {
|
||||
ESP_LOGE(TAG, "failed! mbedtls_x509_crt_parse returned -0x%x while parsing device cert", -ret);
|
||||
return NETWORK_X509_DEVICE_CRT_PARSE_ERROR;
|
||||
}
|
||||
|
||||
/* Parse client private key... */
|
||||
if (pNetwork->tlsConnectParams.pDevicePrivateKeyLocation[0] == '/') {
|
||||
ESP_LOGD(TAG, "Loading client private key from file...");
|
||||
ret = mbedtls_pk_parse_keyfile(&(tlsDataParams->pkey),
|
||||
pNetwork->tlsConnectParams.pDevicePrivateKeyLocation,
|
||||
"");
|
||||
} else {
|
||||
ESP_LOGD(TAG, "Loading embedded client private key...");
|
||||
ret = mbedtls_pk_parse_key(&(tlsDataParams->pkey),
|
||||
(const unsigned char *)pNetwork->tlsConnectParams.pDevicePrivateKeyLocation,
|
||||
strlen(pNetwork->tlsConnectParams.pDevicePrivateKeyLocation)+1,
|
||||
(const unsigned char *)"", 0);
|
||||
}
|
||||
if(ret != 0) {
|
||||
ESP_LOGE(TAG, "failed! mbedtls_pk_parse_key returned -0x%x while parsing private key", -ret);
|
||||
return NETWORK_PK_PRIVATE_KEY_PARSE_ERROR;
|
||||
}
|
||||
|
||||
/* Done parsing certs */
|
||||
ESP_LOGD(TAG, "ok");
|
||||
snprintf(portBuffer, 6, "%d", pNetwork->tlsConnectParams.DestinationPort);
|
||||
ESP_LOGD(TAG, "Connecting to %s/%s...", pNetwork->tlsConnectParams.pDestinationURL, portBuffer);
|
||||
if((ret = mbedtls_net_connect(&(tlsDataParams->server_fd), pNetwork->tlsConnectParams.pDestinationURL,
|
||||
portBuffer, MBEDTLS_NET_PROTO_TCP)) != 0) {
|
||||
ESP_LOGE(TAG, "failed! mbedtls_net_connect returned -0x%x", -ret);
|
||||
switch(ret) {
|
||||
case MBEDTLS_ERR_NET_SOCKET_FAILED:
|
||||
return NETWORK_ERR_NET_SOCKET_FAILED;
|
||||
case MBEDTLS_ERR_NET_UNKNOWN_HOST:
|
||||
return NETWORK_ERR_NET_UNKNOWN_HOST;
|
||||
case MBEDTLS_ERR_NET_CONNECT_FAILED:
|
||||
default:
|
||||
return NETWORK_ERR_NET_CONNECT_FAILED;
|
||||
};
|
||||
}
|
||||
|
||||
ret = mbedtls_net_set_block(&(tlsDataParams->server_fd));
|
||||
if(ret != 0) {
|
||||
ESP_LOGE(TAG, "failed! net_set_(non)block() returned -0x%x", -ret);
|
||||
return SSL_CONNECTION_ERROR;
|
||||
} ESP_LOGD(TAG, "ok");
|
||||
|
||||
ESP_LOGD(TAG, "Setting up the SSL/TLS structure...");
|
||||
if((ret = mbedtls_ssl_config_defaults(&(tlsDataParams->conf), MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM,
|
||||
MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
|
||||
ESP_LOGE(TAG, "failed! mbedtls_ssl_config_defaults returned -0x%x", -ret);
|
||||
return SSL_CONNECTION_ERROR;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_verify(&(tlsDataParams->conf), _iot_tls_verify_cert, NULL);
|
||||
|
||||
if(pNetwork->tlsConnectParams.ServerVerificationFlag == true) {
|
||||
mbedtls_ssl_conf_authmode(&(tlsDataParams->conf), MBEDTLS_SSL_VERIFY_REQUIRED);
|
||||
} else {
|
||||
mbedtls_ssl_conf_authmode(&(tlsDataParams->conf), MBEDTLS_SSL_VERIFY_OPTIONAL);
|
||||
}
|
||||
mbedtls_ssl_conf_rng(&(tlsDataParams->conf), mbedtls_ctr_drbg_random, &(tlsDataParams->ctr_drbg));
|
||||
|
||||
mbedtls_ssl_conf_ca_chain(&(tlsDataParams->conf), &(tlsDataParams->cacert), NULL);
|
||||
ret = mbedtls_ssl_conf_own_cert(&(tlsDataParams->conf), &(tlsDataParams->clicert), &(tlsDataParams->pkey));
|
||||
if(ret != 0) {
|
||||
ESP_LOGE(TAG, "failed! mbedtls_ssl_conf_own_cert returned %d", ret);
|
||||
return SSL_CONNECTION_ERROR;
|
||||
}
|
||||
|
||||
mbedtls_ssl_conf_read_timeout(&(tlsDataParams->conf), pNetwork->tlsConnectParams.timeout_ms);
|
||||
|
||||
if((ret = mbedtls_ssl_setup(&(tlsDataParams->ssl), &(tlsDataParams->conf))) != 0) {
|
||||
ESP_LOGE(TAG, "failed! mbedtls_ssl_setup returned -0x%x", -ret);
|
||||
return SSL_CONNECTION_ERROR;
|
||||
}
|
||||
if((ret = mbedtls_ssl_set_hostname(&(tlsDataParams->ssl), pNetwork->tlsConnectParams.pDestinationURL)) != 0) {
|
||||
ESP_LOGE(TAG, "failed! mbedtls_ssl_set_hostname returned %d", ret);
|
||||
return SSL_CONNECTION_ERROR;
|
||||
}
|
||||
ESP_LOGD(TAG, "SSL state connect : %d ", tlsDataParams->ssl.state);
|
||||
mbedtls_ssl_set_bio(&(tlsDataParams->ssl), &(tlsDataParams->server_fd), mbedtls_net_send, NULL,
|
||||
mbedtls_net_recv_timeout);
|
||||
ESP_LOGD(TAG, "ok");
|
||||
|
||||
ESP_LOGD(TAG, "SSL state connect : %d ", tlsDataParams->ssl.state);
|
||||
ESP_LOGD(TAG, "Performing the SSL/TLS handshake...");
|
||||
while((ret = mbedtls_ssl_handshake(&(tlsDataParams->ssl))) != 0) {
|
||||
if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
|
||||
ESP_LOGE(TAG, "failed! mbedtls_ssl_handshake returned -0x%x", -ret);
|
||||
if(ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) {
|
||||
ESP_LOGE(TAG, " Unable to verify the server's certificate. ");
|
||||
}
|
||||
return SSL_CONNECTION_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "ok [ Protocol is %s ] [ Ciphersuite is %s ]", mbedtls_ssl_get_version(&(tlsDataParams->ssl)),
|
||||
mbedtls_ssl_get_ciphersuite(&(tlsDataParams->ssl)));
|
||||
if((ret = mbedtls_ssl_get_record_expansion(&(tlsDataParams->ssl))) >= 0) {
|
||||
ESP_LOGD(TAG, " [ Record expansion is %d ]", ret);
|
||||
} else {
|
||||
ESP_LOGD(TAG, " [ Record expansion is unknown (compression) ]");
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Verifying peer X.509 certificate...");
|
||||
|
||||
if(pNetwork->tlsConnectParams.ServerVerificationFlag == true) {
|
||||
if((tlsDataParams->flags = mbedtls_ssl_get_verify_result(&(tlsDataParams->ssl))) != 0) {
|
||||
ESP_LOGE(TAG, "failed");
|
||||
mbedtls_x509_crt_verify_info(info_buf, sizeof(info_buf), " ! ", tlsDataParams->flags);
|
||||
ESP_LOGE(TAG, "%s", info_buf);
|
||||
ret = SSL_CONNECTION_ERROR;
|
||||
} else {
|
||||
ESP_LOGD(TAG, "ok");
|
||||
ret = SUCCESS;
|
||||
}
|
||||
} else {
|
||||
ESP_LOGW(TAG, " Server Verification skipped");
|
||||
ret = SUCCESS;
|
||||
}
|
||||
|
||||
if(LOG_LOCAL_LEVEL >= ESP_LOG_DEBUG) {
|
||||
if (mbedtls_ssl_get_peer_cert(&(tlsDataParams->ssl)) != NULL) {
|
||||
ESP_LOGD(TAG, "Peer certificate information:");
|
||||
mbedtls_x509_crt_info((char *) info_buf, sizeof(info_buf) - 1, " ", mbedtls_ssl_get_peer_cert(&(tlsDataParams->ssl)));
|
||||
ESP_LOGD(TAG, "%s", info_buf);
|
||||
}
|
||||
}
|
||||
|
||||
return (IoT_Error_t) ret;
|
||||
}
|
||||
|
||||
IoT_Error_t iot_tls_write(Network *pNetwork, unsigned char *pMsg, size_t len, Timer *timer, size_t *written_len) {
|
||||
size_t written_so_far;
|
||||
bool isErrorFlag = false;
|
||||
int frags, ret = 0;
|
||||
TLSDataParams *tlsDataParams = &(pNetwork->tlsDataParams);
|
||||
|
||||
for(written_so_far = 0, frags = 0;
|
||||
written_so_far < len && !has_timer_expired(timer); written_so_far += ret, frags++) {
|
||||
while(!has_timer_expired(timer) &&
|
||||
(ret = mbedtls_ssl_write(&(tlsDataParams->ssl), pMsg + written_so_far, len - written_so_far)) <= 0) {
|
||||
if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
|
||||
ESP_LOGE(TAG, "failed! mbedtls_ssl_write returned -0x%x", -ret);
|
||||
/* All other negative return values indicate connection needs to be reset.
|
||||
* Will be caught in ping request so ignored here */
|
||||
isErrorFlag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(isErrorFlag) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*written_len = written_so_far;
|
||||
|
||||
if(isErrorFlag) {
|
||||
return NETWORK_SSL_WRITE_ERROR;
|
||||
} else if(has_timer_expired(timer) && written_so_far != len) {
|
||||
return NETWORK_SSL_WRITE_TIMEOUT_ERROR;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
IoT_Error_t iot_tls_read(Network *pNetwork, unsigned char *pMsg, size_t len, Timer *timer, size_t *read_len) {
|
||||
TLSDataParams *tlsDataParams = &(pNetwork->tlsDataParams);
|
||||
mbedtls_ssl_context *ssl = &(tlsDataParams->ssl);
|
||||
mbedtls_ssl_config *ssl_conf = &(tlsDataParams->conf);
|
||||
uint32_t read_timeout;
|
||||
size_t rxLen = 0;
|
||||
int ret;
|
||||
|
||||
read_timeout = ssl_conf->read_timeout;
|
||||
|
||||
while (len > 0) {
|
||||
|
||||
/* Make sure we never block on read for longer than timer has left,
|
||||
but also that we don't block indefinitely (ie read_timeout > 0) */
|
||||
mbedtls_ssl_conf_read_timeout(ssl_conf, MAX(1, MIN(read_timeout, left_ms(timer))));
|
||||
|
||||
ret = mbedtls_ssl_read(ssl, pMsg, len);
|
||||
|
||||
/* Restore the old timeout */
|
||||
mbedtls_ssl_conf_read_timeout(ssl_conf, read_timeout);
|
||||
|
||||
if (ret > 0) {
|
||||
rxLen += ret;
|
||||
pMsg += ret;
|
||||
len -= ret;
|
||||
} else if (ret == 0 || (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE && ret != MBEDTLS_ERR_SSL_TIMEOUT)) {
|
||||
return NETWORK_SSL_READ_ERROR;
|
||||
}
|
||||
|
||||
// Evaluate timeout after the read to make sure read is done at least once
|
||||
if (has_timer_expired(timer)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
*read_len = rxLen;
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
if (rxLen == 0) {
|
||||
return NETWORK_SSL_NOTHING_TO_READ;
|
||||
} else {
|
||||
return NETWORK_SSL_READ_TIMEOUT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
IoT_Error_t iot_tls_disconnect(Network *pNetwork) {
|
||||
mbedtls_ssl_context *ssl = &(pNetwork->tlsDataParams.ssl);
|
||||
int ret = 0;
|
||||
do {
|
||||
ret = mbedtls_ssl_close_notify(ssl);
|
||||
} while(ret == MBEDTLS_ERR_SSL_WANT_WRITE);
|
||||
|
||||
/* All other negative return values indicate connection needs to be reset.
|
||||
* No further action required since this is disconnect call */
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
IoT_Error_t iot_tls_destroy(Network *pNetwork) {
|
||||
TLSDataParams *tlsDataParams = &(pNetwork->tlsDataParams);
|
||||
|
||||
mbedtls_net_free(&(tlsDataParams->server_fd));
|
||||
|
||||
mbedtls_x509_crt_free(&(tlsDataParams->clicert));
|
||||
mbedtls_x509_crt_free(&(tlsDataParams->cacert));
|
||||
mbedtls_pk_free(&(tlsDataParams->pkey));
|
||||
mbedtls_ssl_free(&(tlsDataParams->ssl));
|
||||
mbedtls_ssl_config_free(&(tlsDataParams->conf));
|
||||
mbedtls_ctr_drbg_free(&(tlsDataParams->ctr_drbg));
|
||||
mbedtls_entropy_free(&(tlsDataParams->entropy));
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
104
components/aws_iot/port/threads_freertos.c
Normal file
104
components/aws_iot/port/threads_freertos.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* Additions Copyright 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.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file 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 "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
|
||||
#include "threads_platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Initialize the provided mutex
|
||||
*
|
||||
* Call this function to initialize the mutex
|
||||
*
|
||||
* @param IoT_Mutex_t - pointer to the mutex to be initialized
|
||||
* @return IoT_Error_t - error code indicating result of operation
|
||||
*/
|
||||
IoT_Error_t aws_iot_thread_mutex_init(IoT_Mutex_t *pMutex) {
|
||||
|
||||
pMutex->mutex = xSemaphoreCreateRecursiveMutex();
|
||||
return pMutex->mutex ? SUCCESS : MUTEX_INIT_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Lock the provided mutex
|
||||
*
|
||||
* Call this function to lock the mutex before performing a state change
|
||||
* Blocking, thread will block until lock request fails
|
||||
*
|
||||
* @param IoT_Mutex_t - pointer to the mutex to be locked
|
||||
* @return IoT_Error_t - error code indicating result of operation
|
||||
*/
|
||||
IoT_Error_t aws_iot_thread_mutex_lock(IoT_Mutex_t *pMutex) {
|
||||
xSemaphoreTakeRecursive(pMutex->mutex, portMAX_DELAY);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Try to lock the provided mutex
|
||||
*
|
||||
* Call this function to attempt to lock the mutex before performing a state change
|
||||
* Non-Blocking, immediately returns with failure if lock attempt fails
|
||||
*
|
||||
* @param IoT_Mutex_t - pointer to the mutex to be locked
|
||||
* @return IoT_Error_t - error code indicating result of operation
|
||||
*/
|
||||
IoT_Error_t aws_iot_thread_mutex_trylock(IoT_Mutex_t *pMutex) {
|
||||
if (xSemaphoreTakeRecursive(pMutex->mutex, 0)) {
|
||||
return SUCCESS;
|
||||
} else {
|
||||
return MUTEX_LOCK_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unlock the provided mutex
|
||||
*
|
||||
* Call this function to unlock the mutex before performing a state change
|
||||
*
|
||||
* @param IoT_Mutex_t - pointer to the mutex to be unlocked
|
||||
* @return IoT_Error_t - error code indicating result of operation
|
||||
*/
|
||||
IoT_Error_t aws_iot_thread_mutex_unlock(IoT_Mutex_t *pMutex) {
|
||||
if (xSemaphoreGiveRecursive(pMutex->mutex)) {
|
||||
return SUCCESS;
|
||||
} else {
|
||||
return MUTEX_UNLOCK_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destroy the provided mutex
|
||||
*
|
||||
* Call this function to destroy the mutex
|
||||
*
|
||||
* @param IoT_Mutex_t - pointer to the mutex to be destroyed
|
||||
* @return IoT_Error_t - error code indicating result of operation
|
||||
*/
|
||||
IoT_Error_t aws_iot_thread_mutex_destroy(IoT_Mutex_t *pMutex) {
|
||||
vSemaphoreDelete(pMutex->mutex);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
83
components/aws_iot/port/timer.c
Normal file
83
components/aws_iot/port/timer.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2010-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
* Additions Copyright 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.
|
||||
* A copy of the License is located at
|
||||
*
|
||||
* http://aws.amazon.com/apache2.0
|
||||
*
|
||||
* or in the "license" file accompanying this file. This file 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file timer.c
|
||||
* @brief FreeRTOS implementation of the timer interface uses ticks.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "timer_platform.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
const static char *TAG = "aws_timer";
|
||||
|
||||
bool has_timer_expired(Timer *timer) {
|
||||
uint32_t now = xTaskGetTickCount();
|
||||
bool expired = (now - timer->start_ticks) >= timer->timeout_ticks;
|
||||
|
||||
/* AWS IoT SDK isn't very RTOS friendly because it polls for "done
|
||||
timers" a lot without ever sleeping on them. So we hack in some
|
||||
amount of sleeping here: if it seems like the caller is polling
|
||||
an unexpired timer in a tight loop then we delay a tick to let
|
||||
things progress elsewhere.
|
||||
*/
|
||||
if(!expired && now == timer->last_polled_ticks) {
|
||||
vTaskDelay(1);
|
||||
}
|
||||
timer->last_polled_ticks = now;
|
||||
return expired;
|
||||
}
|
||||
|
||||
void countdown_ms(Timer *timer, uint32_t timeout) {
|
||||
timer->start_ticks = xTaskGetTickCount();
|
||||
timer->timeout_ticks = timeout / portTICK_PERIOD_MS;
|
||||
timer->last_polled_ticks = 0;
|
||||
}
|
||||
|
||||
uint32_t left_ms(Timer *timer) {
|
||||
uint32_t now = xTaskGetTickCount();
|
||||
uint32_t elapsed = now - timer->start_ticks;
|
||||
if (elapsed < timer->timeout_ticks) {
|
||||
return (timer->timeout_ticks - elapsed) * portTICK_PERIOD_MS;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void countdown_sec(Timer *timer, uint32_t timeout) {
|
||||
if (timeout > UINT32_MAX / 1000) {
|
||||
ESP_LOGE(TAG, "timeout is out of range: %ds", timeout);
|
||||
}
|
||||
countdown_ms(timer, timeout * 1000);
|
||||
}
|
||||
|
||||
void init_timer(Timer *timer) {
|
||||
timer->start_ticks = 0;
|
||||
timer->timeout_ticks = 0;
|
||||
timer->last_polled_ticks = 0;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -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,207 @@ 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
|
||||
config BOOTLOADER_VDDSDIO_BOOST
|
||||
bool "Increase VDDSDIO LDO voltage to 1.9V"
|
||||
default y
|
||||
help
|
||||
If this option is enabled, and VDDSDIO LDO is set to 1.8V (using EFUSE
|
||||
or MTDI bootstrapping pin), bootloader will change LDO settings to
|
||||
output 1.9V instead. This helps prevent flash chip from browning out
|
||||
during flash programming operations.
|
||||
For 3.3V flash, this option has no effect.
|
||||
|
||||
endmenu # Bootloader
|
||||
|
||||
|
||||
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= TESTS_ALL=
|
||||
|
||||
.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 soc
|
||||
|
||||
# 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,120 +20,24 @@
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#define BOOT_VERSION "V0.1"
|
||||
|
||||
#include "esp_flash_data_types.h"
|
||||
#include "soc/soc.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
|
||||
#define DROM_HIGH 0x3F800000
|
||||
#define RTC_IRAM_LOW 0x400C0000
|
||||
#define RTC_IRAM_HIGH 0x400C2000
|
||||
#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
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,20 @@
|
||||
#
|
||||
# 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 \
|
||||
$(IDF_PATH)/components/esp32/ld/esp32.peripherals.ld \
|
||||
esp32.bootloader.rom.ld
|
||||
|
||||
include $(IDF_PATH)/make/component_common.mk
|
||||
ifndef CONFIG_SPI_FLASH_ROM_DRIVER_PATCH
|
||||
LINKER_SCRIPTS += $(IDF_PATH)/components/esp32/ld/esp32.rom.spiflash.ld
|
||||
endif
|
||||
|
||||
COMPONENT_ADD_LDFLAGS := -L $(COMPONENT_PATH) -lmain $(addprefix -T ,$(LINKER_SCRIPTS))
|
||||
|
||||
COMPONENT_ADD_LINKER_DEPS := $(LINKER_SCRIPTS)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
266
components/bootloader/src/main/flash_qio_mode.c
Normal file
266
components/bootloader/src/main/flash_qio_mode.c
Normal file
@@ -0,0 +1,266 @@
|
||||
// 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 <stdint.h>
|
||||
#include "flash_qio_mode.h"
|
||||
#include "esp_log.h"
|
||||
#include "rom/spi_flash.h"
|
||||
#include "rom/efuse.h"
|
||||
#include "soc/spi_struct.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
/* SPI flash controller */
|
||||
#define SPIFLASH SPI1
|
||||
|
||||
/* SPI commands (actual on-wire commands not SPI controller bitmasks)
|
||||
Suitable for use with the execute_flash_command static function.
|
||||
*/
|
||||
#define CMD_RDID 0x9F
|
||||
#define CMD_WRSR 0x01
|
||||
#define CMD_WRSR2 0x31 /* Not all SPI flash uses this command */
|
||||
#define CMD_WREN 0x06
|
||||
#define CMD_WRDI 0x04
|
||||
#define CMD_RDSR 0x05
|
||||
#define CMD_RDSR2 0x35 /* Not all SPI flash uses this command */
|
||||
|
||||
|
||||
#define ESP32_D2WD_WP_GPIO 7 /* ESP32-D2WD has this GPIO wired to WP pin of flash */
|
||||
|
||||
static const char *TAG = "qio_mode";
|
||||
|
||||
typedef unsigned (*read_status_fn_t)();
|
||||
typedef void (*write_status_fn_t)(unsigned);
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
const char *manufacturer;
|
||||
uint8_t mfg_id; /* 8-bit JEDEC manufacturer ID */
|
||||
uint16_t flash_id; /* 16-bit JEDEC flash chip ID */
|
||||
uint16_t id_mask; /* Bits to match on in flash chip ID */
|
||||
read_status_fn_t read_status_fn;
|
||||
write_status_fn_t write_status_fn;
|
||||
uint8_t status_qio_bit;
|
||||
} qio_info_t;
|
||||
|
||||
/* Read 8 bit status using RDSR command */
|
||||
static unsigned read_status_8b_rdsr();
|
||||
/* Read 8 bit status (second byte) using RDSR2 command */
|
||||
static unsigned read_status_8b_rdsr2();
|
||||
/* read 16 bit status using RDSR & RDSR2 (low and high bytes) */
|
||||
static unsigned read_status_16b_rdsr_rdsr2();
|
||||
|
||||
/* Write 8 bit status using WRSR */
|
||||
static void write_status_8b_wrsr(unsigned new_status);
|
||||
/* Write 8 bit status (second byte) using WRSR2 */
|
||||
static void write_status_8b_wrsr2(unsigned new_status);
|
||||
/* Write 16 bit status using WRSR */
|
||||
static void write_status_16b_wrsr(unsigned new_status);
|
||||
|
||||
/* Array of known flash chips and data to enable Quad I/O mode
|
||||
|
||||
Manufacturer & flash ID can be tested by running "esptool.py
|
||||
flash_id"
|
||||
|
||||
If manufacturer ID matches, and flash ID ORed with flash ID mask
|
||||
matches, enable_qio_mode() will execute "Read Cmd", test if bit
|
||||
number "QIE Bit" is set, and if not set it will call "Write Cmd"
|
||||
with this bit set.
|
||||
|
||||
Searching of this table stops when the first match is found.
|
||||
*/
|
||||
const static qio_info_t chip_data[] = {
|
||||
/* Manufacturer, mfg_id, flash_id, id mask, Read Status, Write Status, QIE Bit */
|
||||
{ "MXIC", 0xC2, 0x2000, 0xFF00, read_status_8b_rdsr, write_status_8b_wrsr, 6 },
|
||||
{ "ISSI", 0x9D, 0x4000, 0xCF00, read_status_8b_rdsr, write_status_8b_wrsr, 6 }, /* IDs 0x40xx, 0x70xx */
|
||||
{ "WinBond", 0xEF, 0x4000, 0xFF00, read_status_16b_rdsr_rdsr2, write_status_16b_wrsr, 9 },
|
||||
|
||||
/* Final entry is default entry, if no other IDs have matched.
|
||||
|
||||
This approach works for chips including:
|
||||
GigaDevice (mfg ID 0xC8, flash IDs including 4016),
|
||||
FM25Q32 (QOUT mode only, mfg ID 0xA1, flash IDs including 4016)
|
||||
*/
|
||||
{ NULL, 0xFF, 0xFFFF, 0xFFFF, read_status_8b_rdsr2, write_status_8b_wrsr2, 1 },
|
||||
};
|
||||
|
||||
#define NUM_CHIPS (sizeof(chip_data) / sizeof(qio_info_t))
|
||||
|
||||
static void enable_qio_mode(read_status_fn_t read_status_fn,
|
||||
write_status_fn_t write_status_fn,
|
||||
uint8_t status_qio_bit);
|
||||
|
||||
/* Generic function to use the "user command" SPI controller functionality
|
||||
to send commands to the SPI flash and read the respopnse.
|
||||
|
||||
The command passed here is always the on-the-wire command given to the SPI flash unit.
|
||||
*/
|
||||
static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len);
|
||||
|
||||
/* dummy_len_plus values defined in ROM for SPI flash configuration */
|
||||
extern uint8_t g_rom_spiflash_dummy_len_plus[];
|
||||
|
||||
void bootloader_enable_qio_mode(void)
|
||||
{
|
||||
uint32_t raw_flash_id;
|
||||
uint8_t mfg_id;
|
||||
uint16_t flash_id;
|
||||
int i;
|
||||
|
||||
ESP_LOGD(TAG, "Probing for QIO mode enable...");
|
||||
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
||||
|
||||
/* Set up some of the SPIFLASH user/ctrl variables which don't change
|
||||
while we're probing using execute_flash_command() */
|
||||
SPIFLASH.ctrl.val = 0;
|
||||
SPIFLASH.user.usr_dummy = 0;
|
||||
SPIFLASH.user.usr_addr = 0;
|
||||
SPIFLASH.user.usr_command = 1;
|
||||
SPIFLASH.user2.usr_command_bitlen = 7;
|
||||
|
||||
raw_flash_id = execute_flash_command(CMD_RDID, 0, 0, 24);
|
||||
ESP_LOGD(TAG, "Raw SPI flash chip id 0x%x", raw_flash_id);
|
||||
|
||||
mfg_id = raw_flash_id & 0xFF;
|
||||
flash_id = (raw_flash_id >> 16) | (raw_flash_id & 0xFF00);
|
||||
ESP_LOGD(TAG, "Manufacturer ID 0x%02x chip ID 0x%04x", mfg_id, flash_id);
|
||||
|
||||
for (i = 0; i < NUM_CHIPS-1; i++) {
|
||||
const qio_info_t *chip = &chip_data[i];
|
||||
if (mfg_id == chip->mfg_id && (flash_id & chip->id_mask) == (chip->flash_id & chip->id_mask)) {
|
||||
ESP_LOGI(TAG, "Enabling QIO for flash chip %s", chip_data[i].manufacturer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i == NUM_CHIPS - 1) {
|
||||
ESP_LOGI(TAG, "Enabling default flash chip QIO");
|
||||
}
|
||||
|
||||
enable_qio_mode(chip_data[i].read_status_fn,
|
||||
chip_data[i].write_status_fn,
|
||||
chip_data[i].status_qio_bit);
|
||||
}
|
||||
|
||||
static void enable_qio_mode(read_status_fn_t read_status_fn,
|
||||
write_status_fn_t write_status_fn,
|
||||
uint8_t status_qio_bit)
|
||||
{
|
||||
uint32_t status;
|
||||
const uint32_t spiconfig = ets_efuse_get_spiconfig();
|
||||
|
||||
if (spiconfig != EFUSE_SPICONFIG_SPI_DEFAULTS && spiconfig != EFUSE_SPICONFIG_HSPI_DEFAULTS) {
|
||||
// spiconfig specifies a custom efuse pin configuration. This config defines all pins -except- WP.
|
||||
//
|
||||
// For now, in this situation we only support Quad I/O mode for ESP32-D2WD where WP pin is known.
|
||||
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
|
||||
uint32_t pkg_ver = chip_ver & 0x7;
|
||||
const uint32_t PKG_VER_ESP32_D2WD = 2; // TODO: use chip detection API once available
|
||||
if (pkg_ver != PKG_VER_ESP32_D2WD) {
|
||||
ESP_LOGE(TAG, "Quad I/O is only supported for standard pin numbers or ESP32-D2WD. Falling back to Dual I/O.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
||||
|
||||
status = read_status_fn();
|
||||
ESP_LOGD(TAG, "Initial flash chip status 0x%x", status);
|
||||
|
||||
if ((status & (1<<status_qio_bit)) == 0) {
|
||||
execute_flash_command(CMD_WREN, 0, 0, 0);
|
||||
write_status_fn(status | (1<<status_qio_bit));
|
||||
|
||||
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
||||
|
||||
status = read_status_fn();
|
||||
ESP_LOGD(TAG, "Updated flash chip status 0x%x", status);
|
||||
if ((status & (1<<status_qio_bit)) == 0) {
|
||||
ESP_LOGE(TAG, "Failed to set QIE bit, not enabling QIO mode");
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
ESP_LOGD(TAG, "QIO mode already enabled in flash");
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "Enabling QIO mode...");
|
||||
|
||||
esp_rom_spiflash_read_mode_t mode;
|
||||
#if CONFIG_FLASHMODE_QOUT
|
||||
mode = ESP_ROM_SPIFLASH_QOUT_MODE;
|
||||
#else
|
||||
mode = ESP_ROM_SPIFLASH_QIO_MODE;
|
||||
#endif
|
||||
|
||||
esp_rom_spiflash_config_readmode(mode);
|
||||
|
||||
esp_rom_spiflash_select_qio_pins(ESP32_D2WD_WP_GPIO, spiconfig);
|
||||
}
|
||||
|
||||
static unsigned read_status_8b_rdsr()
|
||||
{
|
||||
return execute_flash_command(CMD_RDSR, 0, 0, 8);
|
||||
}
|
||||
|
||||
static unsigned read_status_8b_rdsr2()
|
||||
{
|
||||
return execute_flash_command(CMD_RDSR2, 0, 0, 8);
|
||||
}
|
||||
|
||||
static unsigned read_status_16b_rdsr_rdsr2()
|
||||
{
|
||||
return execute_flash_command(CMD_RDSR, 0, 0, 8) | (execute_flash_command(CMD_RDSR2, 0, 0, 8) << 8);
|
||||
}
|
||||
|
||||
static void write_status_8b_wrsr(unsigned new_status)
|
||||
{
|
||||
execute_flash_command(CMD_WRSR, new_status, 8, 0);
|
||||
}
|
||||
|
||||
static void write_status_8b_wrsr2(unsigned new_status)
|
||||
{
|
||||
execute_flash_command(CMD_WRSR2, new_status, 8, 0);
|
||||
}
|
||||
|
||||
static void write_status_16b_wrsr(unsigned new_status)
|
||||
{
|
||||
execute_flash_command(CMD_WRSR, new_status, 16, 0);
|
||||
}
|
||||
|
||||
static uint32_t execute_flash_command(uint8_t command, uint32_t mosi_data, uint8_t mosi_len, uint8_t miso_len)
|
||||
{
|
||||
SPIFLASH.user2.usr_command_value = command;
|
||||
SPIFLASH.user.usr_miso = miso_len > 0;
|
||||
SPIFLASH.miso_dlen.usr_miso_dbitlen = miso_len ? (miso_len - 1) : 0;
|
||||
SPIFLASH.user.usr_mosi = mosi_len > 0;
|
||||
SPIFLASH.mosi_dlen.usr_mosi_dbitlen = mosi_len ? (mosi_len - 1) : 0;
|
||||
SPIFLASH.data_buf[0] = mosi_data;
|
||||
|
||||
if (g_rom_spiflash_dummy_len_plus[1]) {
|
||||
/* When flash pins are mapped via GPIO matrix, need a dummy cycle before reading via MISO */
|
||||
if (miso_len > 0) {
|
||||
SPIFLASH.user.usr_dummy = 1;
|
||||
SPIFLASH.user1.usr_dummy_cyclelen = g_rom_spiflash_dummy_len_plus[1] - 1;
|
||||
} else {
|
||||
SPIFLASH.user.usr_dummy = 0;
|
||||
SPIFLASH.user1.usr_dummy_cyclelen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
SPIFLASH.cmd.usr = 1;
|
||||
while(SPIFLASH.cmd.usr != 0)
|
||||
{ }
|
||||
|
||||
return SPIFLASH.data_buf[0];
|
||||
}
|
||||
29
components/bootloader/src/main/flash_qio_mode.h
Normal file
29
components/bootloader/src/main/flash_qio_mode.h
Normal file
@@ -0,0 +1,29 @@
|
||||
// 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.
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @brief Enable Quad I/O mode in bootloader (if configured)
|
||||
*
|
||||
* Queries attached SPI flash ID and sends correct SPI flash
|
||||
* commands to enable QIO or QOUT mode, then enables this mode.
|
||||
*/
|
||||
void bootloader_enable_qio_mode(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -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 /** @cond */ IRAM_ATTR /** @endcond */ 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);
|
||||
246
components/bootloader_support/src/bootloader_flash.c
Normal file
246
components/bootloader_support/src/bootloader_flash.c
Normal file
@@ -0,0 +1,246 @@
|
||||
// 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 );
|
||||
int e = cache_flash_mmu_set(0, 0, MMU_BLOCK0_VADDR, src_addr_aligned, 64, count);
|
||||
if (e != 0) {
|
||||
ESP_LOGE(TAG, "cache_flash_mmu_set failed: %d\n", e);
|
||||
Cache_Read_Enable(0);
|
||||
return NULL;
|
||||
}
|
||||
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(esp_rom_spiflash_result_t r)
|
||||
{
|
||||
switch(r) {
|
||||
case ESP_ROM_SPIFLASH_RESULT_OK:
|
||||
return ESP_OK;
|
||||
case ESP_ROM_SPIFLASH_RESULT_ERR:
|
||||
return ESP_ERR_FLASH_OP_FAIL;
|
||||
case ESP_ROM_SPIFLASH_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);
|
||||
esp_rom_spiflash_result_t r = esp_rom_spiflash_read(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(esp_rom_spiflash_unlock());
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (write_encrypted) {
|
||||
return spi_to_esp_err(esp_rom_spiflash_write_encrypted(dest_addr, src, size));
|
||||
} else {
|
||||
return spi_to_esp_err(esp_rom_spiflash_write(dest_addr, src, size));
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t bootloader_flash_erase_sector(size_t sector)
|
||||
{
|
||||
return spi_to_esp_err(esp_rom_spiflash_erase_sector(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.
|
||||
*/
|
||||
DPORT_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);
|
||||
|
||||
DPORT_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 */
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
|
||||
|
||||
|
||||
/* Reset some i2s configuration (possibly redundant as we reset entire
|
||||
I2S peripheral further down). */
|
||||
CLEAR_PERI_REG_MASK(I2S_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 */
|
||||
DPORT_SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
|
||||
DPORT_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);
|
||||
}
|
||||
}
|
||||
}
|
||||
189
components/bootloader_support/src/esp_image_format.c
Normal file
189
components/bootloader_support/src/esp_image_format.c
Normal file
@@ -0,0 +1,189 @@
|
||||
// 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;
|
||||
}
|
||||
|
||||
uint32_t load_addr = segment_header.load_addr;
|
||||
bool map_segment = (load_addr >= SOC_DROM_LOW && load_addr < SOC_DROM_HIGH)
|
||||
|| (load_addr >= SOC_IROM_LOW && load_addr < SOC_IROM_HIGH);
|
||||
|
||||
|
||||
/* Check that flash cache mapped segment aligns correctly from flash it's mapped address,
|
||||
relative to the 64KB page mapping size.
|
||||
*/
|
||||
ESP_LOGV(TAG, "segment %d map_segment %d segment_data_offs 0x%x load_addr 0x%x",
|
||||
i, map_segment, segment_data_offs, load_addr);
|
||||
if (map_segment && ((segment_data_offs % SPI_FLASH_MMU_PAGE_SIZE) != (load_addr % SPI_FLASH_MMU_PAGE_SIZE))) {
|
||||
ESP_LOGE(TAG, "Segment %d has load address 0x%08x, conflict with segment data at 0x%08x",
|
||||
i, load_addr, segment_data_offs);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
4
components/bootloader_support/test/component.mk
Normal file
4
components/bootloader_support/test/component.mk
Normal file
@@ -0,0 +1,4 @@
|
||||
#
|
||||
#Component Makefile
|
||||
#
|
||||
COMPONENT_ADD_LDFLAGS = -Wl,--whole-archive -l$(COMPONENT_NAME) -Wl,--no-whole-archive
|
||||
37
components/bootloader_support/test/test_verify_image.c
Normal file
37
components/bootloader_support/test/test_verify_image.c
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Tests for bootloader_support esp_image_basic_verify()
|
||||
*/
|
||||
|
||||
#include <esp_types.h>
|
||||
#include <stdio.h>
|
||||
#include "rom/ets_sys.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "unity.h"
|
||||
|
||||
#include "esp_partition.h"
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_image_format.h"
|
||||
|
||||
TEST_CASE("Verify bootloader image in flash", "[bootloader_support]")
|
||||
{
|
||||
uint32_t image_len = 0;
|
||||
TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_basic_verify(0x1000, true, &image_len));
|
||||
TEST_ASSERT_NOT_EQUAL(0, image_len);
|
||||
}
|
||||
|
||||
TEST_CASE("Verify unit test app image", "[bootloader_support]")
|
||||
{
|
||||
uint32_t image_len = 0;
|
||||
const esp_partition_t *running = esp_ota_get_running_partition();
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, running);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX(ESP_OK, esp_image_basic_verify(running->address, true, &image_len));
|
||||
TEST_ASSERT_NOT_EQUAL(0, image_len);
|
||||
TEST_ASSERT_TRUE(image_len <= running->size);
|
||||
}
|
||||
|
||||
@@ -1,29 +1,126 @@
|
||||
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 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
|
||||
menuconfig BLUEDROID_ENABLED
|
||||
bool "Bluedroid Bluetooth stack enabled"
|
||||
depends on BT_ENABLED
|
||||
default y
|
||||
help
|
||||
This enables the default Bluedroid Bluetooth stack
|
||||
|
||||
endmenu
|
||||
config BTC_TASK_STACK_SIZE
|
||||
int "Bluetooth event (callback to application) task stack size"
|
||||
depends on BLUEDROID_ENABLED
|
||||
default 3072
|
||||
help
|
||||
This select btc task stack size
|
||||
|
||||
config BLUEDROID_MEM_DEBUG
|
||||
bool "Bluedroid memory debug"
|
||||
depends on BLUEDROID_ENABLED
|
||||
default n
|
||||
help
|
||||
Bluedroid memory debug
|
||||
|
||||
config CLASSIC_BT_ENABLED
|
||||
bool "Classic Bluetooth"
|
||||
depends on BLUEDROID_ENABLED
|
||||
default n
|
||||
help
|
||||
For now this option needs "SMP_ENABLE" to be set to yes
|
||||
|
||||
config BT_DRAM_RELEASE
|
||||
bool "Release DRAM from Classic BT controller"
|
||||
depends on BT_ENABLED && (!BLUEDROID_ENABLED || (BLUEDROID_ENABLED && !CLASSIC_BT_ENABLED))
|
||||
default n
|
||||
help
|
||||
This option should only be used when BLE only.
|
||||
Enabling this option will release about 30K DRAM from Classic BT.
|
||||
The released DRAM will be used as system heap memory.
|
||||
|
||||
config GATTS_ENABLE
|
||||
bool "Include GATT server module(GATTS)"
|
||||
depends on BLUEDROID_ENABLED
|
||||
default y
|
||||
help
|
||||
This option can be disabled when the app work only on gatt client mode
|
||||
|
||||
config GATTC_ENABLE
|
||||
bool "Include GATT client module(GATTC)"
|
||||
depends on BLUEDROID_ENABLED
|
||||
default y
|
||||
help
|
||||
This option can be close when the app work only on gatt server mode
|
||||
|
||||
config BLE_SMP_ENABLE
|
||||
bool "Include BLE security module(SMP)"
|
||||
depends on BLUEDROID_ENABLED
|
||||
default y
|
||||
help
|
||||
This option can be close when the app not used the ble security connect.
|
||||
|
||||
config BT_STACK_NO_LOG
|
||||
bool "Close the bluedroid bt stack log print"
|
||||
depends on BLUEDROID_ENABLED
|
||||
default n
|
||||
help
|
||||
This select can save the rodata code size
|
||||
|
||||
config BT_ACL_CONNECTIONS
|
||||
int "BT/BLE MAX ACL CONNECTIONS(1~7)"
|
||||
depends on BLUEDROID_ENABLED
|
||||
range 1 7
|
||||
default 4
|
||||
help
|
||||
Maximum BT/BLE connection count
|
||||
|
||||
#disable now for app cpu due to a known issue
|
||||
config BTDM_CONTROLLER_RUN_APP_CPU
|
||||
bool "Run controller on APP CPU"
|
||||
depends on BT_ENABLED && !FREERTOS_UNICORE && 0
|
||||
default n
|
||||
help
|
||||
Run controller on APP CPU.
|
||||
|
||||
config BTDM_CONTROLLER_RUN_CPU
|
||||
int
|
||||
depends on BT_ENABLED
|
||||
default 1 if BTDM_CONTROLLER_RUN_APP_CPU
|
||||
default 0
|
||||
|
||||
menuconfig BT_HCI_UART
|
||||
bool "HCI use UART as IO"
|
||||
depends on BT_ENABLED && !BLUEDROID_ENABLED
|
||||
default n
|
||||
help
|
||||
Default HCI use VHCI, if this option choose, HCI will use UART(0/1/2) as IO.
|
||||
Besides, it can set uart number and uart baudrate.
|
||||
|
||||
config BT_HCI_UART_NO
|
||||
int "UART Number for HCI"
|
||||
depends on BT_HCI_UART
|
||||
range 1 2
|
||||
default 1
|
||||
help
|
||||
Uart number for HCI.
|
||||
|
||||
config BT_HCI_UART_BAUDRATE
|
||||
int "UART Baudrate for HCI"
|
||||
depends on BT_HCI_UART
|
||||
range 115200 921600
|
||||
default 921600
|
||||
help
|
||||
UART Baudrate for HCI. Please use standard baudrate.
|
||||
|
||||
config SMP_ENABLE
|
||||
bool
|
||||
depends on BLUEDROID_ENABLED
|
||||
default CLASSIC_BT_ENABLED || BLE_SMP_ENABLE
|
||||
|
||||
# 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
|
||||
|
||||
133
components/bt/bluedroid/api/esp_a2dp_api.c
Normal file
133
components/bt/bluedroid/api/esp_a2dp_api.c
Normal file
@@ -0,0 +1,133 @@
|
||||
// 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 "bt_target.h"
|
||||
#include <string.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_a2dp_api.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "btc_manage.h"
|
||||
#include "btc_av.h"
|
||||
|
||||
#if BTC_AV_INCLUDED
|
||||
|
||||
esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (callback == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_profile_cb_set(BTC_PID_A2DP, callback);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_a2d_sink_init(void)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_A2DP;
|
||||
msg.act = BTC_AV_SINK_API_INIT_EVT;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_a2d_sink_deinit(void)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_A2DP;
|
||||
msg.act = BTC_AV_SINK_API_DEINIT_EVT;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_a2d_register_data_callback(esp_a2d_data_cb_t callback)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_A2DP;
|
||||
msg.act = BTC_AV_SINK_API_REG_DATA_CB_EVT;
|
||||
|
||||
btc_av_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_av_args_t));
|
||||
arg.data_cb = callback;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_msg_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
bt_status_t stat;
|
||||
btc_av_args_t arg;
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_A2DP;
|
||||
msg.act = BTC_AV_SINK_API_CONNECT_EVT;
|
||||
|
||||
memset(&arg, 0, sizeof(btc_av_args_t));
|
||||
|
||||
/* Switch to BTC context */
|
||||
memcpy(&(arg.connect), remote_bda, sizeof(bt_bdaddr_t));
|
||||
stat = btc_transfer_context(&msg, &arg, sizeof(btc_av_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
bt_status_t stat;
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_A2DP;
|
||||
msg.act = BTC_AV_SINK_API_DISCONNECT_EVT;
|
||||
|
||||
/* Switch to BTC context */
|
||||
stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
#endif /* #if BTC_AV_INCLUDED */
|
||||
96
components/bt/bluedroid/api/esp_avrc_api.c
Normal file
96
components/bt/bluedroid/api/esp_avrc_api.c
Normal file
@@ -0,0 +1,96 @@
|
||||
// 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 "bt_target.h"
|
||||
#include <string.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_avrc_api.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "btc_manage.h"
|
||||
#include "btc_avrc.h"
|
||||
|
||||
#if BTC_AV_INCLUDED
|
||||
|
||||
esp_err_t esp_avrc_ct_register_callback(esp_avrc_ct_cb_t callback)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (callback == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_profile_cb_set(BTC_PID_AVRC, callback);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_ct_init(void)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC;
|
||||
msg.act = BTC_AVRC_CTRL_API_INIT_EVT;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_ct_deinit(void)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC;
|
||||
msg.act = BTC_AVRC_CTRL_API_DEINIT_EVT;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t key_state)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_AVRC;
|
||||
msg.act = BTC_AVRC_CTRL_API_SND_PTCMD_EVT;
|
||||
|
||||
btc_avrc_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_avrc_args_t));
|
||||
|
||||
arg.pt_cmd.tl = tl;
|
||||
arg.pt_cmd.key_code = key_code;
|
||||
arg.pt_cmd.key_state = key_state;
|
||||
|
||||
/* Switch to BTC context */
|
||||
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL);
|
||||
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
#endif /* #if BTC_AV_INCLUDED */
|
||||
109
components/bt/bluedroid/api/esp_blufi_api.c
Normal file
109
components/bt/bluedroid/api/esp_blufi_api.c
Normal file
@@ -0,0 +1,109 @@
|
||||
// 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"
|
||||
#include "btc_gatts.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();
|
||||
}
|
||||
|
||||
esp_err_t esp_blufi_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 = conn_id;
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t), NULL)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
50
components/bt/bluedroid/api/esp_bt_device.c
Normal file
50
components/bt/bluedroid/api/esp_bt_device.c
Normal file
@@ -0,0 +1,50 @@
|
||||
// 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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "esp_bt_device.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "controller.h"
|
||||
#include "btc_task.h"
|
||||
#include "btc_dev.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;
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_dev_set_device_name(const char *name)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_dev_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (strlen(name) > ESP_DEV_DEVICE_NAME_MAX) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_DEV;
|
||||
msg.act = BTC_DEV_ACT_SET_DEVICE_NAME;
|
||||
strcpy(arg.set_dev_name.device_name, name);
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_dev_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
205
components/bt/bluedroid/api/esp_bt_main.c
Normal file
205
components/bt/bluedroid/api/esp_bt_main.c
Normal file
@@ -0,0 +1,205 @@
|
||||
// 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;
|
||||
|
||||
if (btc_transfer_context(&msg, NULL, 0, NULL) != BT_STATUS_SUCCESS) {
|
||||
LOG_ERROR("Bluedroid enable failed\n");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (btc_transfer_context(&msg, NULL, 0, NULL) != BT_STATUS_SUCCESS) {
|
||||
LOG_ERROR("Bluedroid disable failed\n");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BLUEDROID_MEM_DEBUG
|
||||
osi_mem_dbg_init();
|
||||
#endif
|
||||
|
||||
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;
|
||||
|
||||
if (btc_transfer_context(&msg, NULL, 0, NULL) != BT_STATUS_SUCCESS) {
|
||||
LOG_ERROR("Bluedroid initialise failed\n");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (btc_transfer_context(&msg, NULL, 0, NULL) != BT_STATUS_SUCCESS) {
|
||||
LOG_ERROR("Bluedroid de-initialise failed\n");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
414
components/bt/bluedroid/api/esp_gap_ble_api.c
Normal file
414
components/bt/bluedroid/api/esp_gap_ble_api.c
Normal file
@@ -0,0 +1,414 @@
|
||||
// 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_device.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"
|
||||
#include "btc_ble_storage.h"
|
||||
|
||||
|
||||
esp_err_t esp_ble_gap_register_callback(esp_gap_ble_cb_t callback)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
return esp_bt_dev_set_device_name(name);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
#if (SMP_INCLUDED)
|
||||
esp_err_t esp_ble_gap_set_security_param(esp_ble_sm_param_t param_type,
|
||||
void *value, uint8_t len)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_SET_SECURITY_PARAM_EVT;
|
||||
arg.set_security_param.param_type = param_type;
|
||||
arg.set_security_param.len = len;
|
||||
arg.set_security_param.value = value;
|
||||
|
||||
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_set_encryption(esp_bd_addr_t bd_addr, esp_ble_sec_act_t sec_act)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_SET_ENCRYPTION_EVT;
|
||||
arg.set_encryption.sec_act = sec_act;
|
||||
memcpy(arg.set_encryption.bd_addr, bd_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_security_rsp(esp_bd_addr_t bd_addr, bool accept)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_SECURITY_RSP_EVT;
|
||||
arg.sec_rsp.accept = accept;
|
||||
memcpy(arg.sec_rsp.bd_addr, bd_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_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t passkey)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_PASSKEY_REPLY_EVT;
|
||||
arg.enc_passkey_replay.accept = accept;
|
||||
arg.enc_passkey_replay.passkey = passkey;
|
||||
memcpy(arg.enc_passkey_replay.bd_addr, bd_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_confirm_reply(esp_bd_addr_t bd_addr, bool accept)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_CONFIRM_REPLY_EVT;
|
||||
arg.enc_comfirm_replay.accept = accept;
|
||||
memcpy(arg.enc_comfirm_replay.bd_addr, bd_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_remove_bond_device(esp_bd_addr_t bd_addr)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_REMOVE_BOND_DEV_EVT;
|
||||
memcpy(arg.remove_bond_device.bd_addr, bd_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);
|
||||
}
|
||||
|
||||
int esp_ble_get_bond_device_num(void)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
return btc_storage_get_num_ble_bond_devices();
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_get_bond_device_list(int *dev_num, esp_ble_bond_dev_t *dev_list)
|
||||
{
|
||||
int ret;
|
||||
int dev_num_total;
|
||||
|
||||
if (dev_num == NULL || dev_list == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
dev_num_total = btc_storage_get_num_ble_bond_devices();
|
||||
if (*dev_num > dev_num_total) {
|
||||
*dev_num = dev_num_total;
|
||||
}
|
||||
|
||||
ret = btc_storage_get_bonded_ble_devices_list(dev_list, *dev_num);
|
||||
|
||||
return (ret == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
#endif /* #if (SMP_INCLUDED) */
|
||||
|
||||
esp_err_t esp_ble_gap_disconnect(esp_bd_addr_t remote_device)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_DISCONNECT_EVT;
|
||||
memcpy(arg.disconnect.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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
42
components/bt/bluedroid/api/esp_gap_bt_api.c
Normal file
42
components/bt/bluedroid/api/esp_gap_bt_api.c
Normal file
@@ -0,0 +1,42 @@
|
||||
// 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 "bt_target.h"
|
||||
#include <string.h>
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_gap_bt_api.h"
|
||||
#include "bt_trace.h"
|
||||
#include "btc_manage.h"
|
||||
#include "btc_gap_bt.h"
|
||||
|
||||
#if BTC_GAP_BT_INCLUDED
|
||||
|
||||
esp_err_t esp_bt_gap_set_scan_mode(esp_bt_scan_mode_t mode)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_gap_bt_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_BT;
|
||||
msg.act = BTC_GAP_BT_ACT_SET_SCAN_MODE;
|
||||
arg.set_scan_mode.mode = mode;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_gap_bt_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
#endif /* #if BTC_GAP_BT_INCLUDED */
|
||||
463
components/bt/bluedroid/api/esp_gattc_api.c
Normal file
463
components/bt/bluedroid/api/esp_gattc_api.c
Normal file
@@ -0,0 +1,463 @@
|
||||
// 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"
|
||||
|
||||
#if (GATTC_INCLUDED == TRUE)
|
||||
esp_err_t esp_ble_gattc_register_callback(esp_gattc_cb_t callback)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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_prepare_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 offset,
|
||||
uint16_t value_len,
|
||||
uint8_t *value,
|
||||
esp_gatt_auth_req_t auth_req)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_PREPARE_WRITE_CHAR_DESCR;
|
||||
arg.prep_write_descr.conn_id = BTC_GATT_CREATE_CONN_ID(gattc_if, conn_id);
|
||||
memcpy(&arg.prep_write_descr.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
|
||||
memcpy(&arg.prep_write_descr.char_id, char_id, sizeof(esp_gatt_id_t));
|
||||
memcpy(&arg.prep_write_descr.descr_id, descr_id, sizeof(esp_gatt_id_t));
|
||||
arg.prep_write_descr.offset = offset;
|
||||
arg.prep_write_descr.value_len = value_len > ESP_GATT_MAX_ATTR_LEN ? ESP_GATT_MAX_ATTR_LEN : value_len; // length check ?
|
||||
arg.prep_write_descr.value = value;
|
||||
arg.prep_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_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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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_err_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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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_err_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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_cache_refresh(esp_bd_addr_t remote_bda)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_CACHE_REFRESH;
|
||||
memcpy(arg.cache_refresh.remote_bda, remote_bda, sizeof(esp_bd_addr_t));
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
#endif ///GATTC_INCLUDED == TRUE
|
||||
|
||||
380
components/bt/bluedroid/api/esp_gatts_api.c
Normal file
380
components/bt/bluedroid/api/esp_gatts_api.c
Normal file
@@ -0,0 +1,380 @@
|
||||
// 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"
|
||||
#include "bt_target.h"
|
||||
#if (GATTS_INCLUDED == TRUE)
|
||||
#define COPY_TO_GATTS_ARGS(_gatt_args, _arg, _arg_type) memcpy(_gatt_args, _arg, sizeof(_arg_type))
|
||||
|
||||
static esp_err_t esp_ble_gatts_add_char_desc_param_check(esp_attr_value_t *char_val, esp_attr_control_t *control);
|
||||
|
||||
|
||||
esp_err_t esp_ble_gatts_register_callback(esp_gatts_cb_t callback)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
//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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
esp_err_t status;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
/* parameter validation check */
|
||||
status = esp_ble_gatts_add_char_desc_param_check(char_val, control);
|
||||
if (status != ESP_OK){
|
||||
return status;
|
||||
}
|
||||
|
||||
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;
|
||||
esp_err_t status;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
/* parameter validation check */
|
||||
status = esp_ble_gatts_add_char_desc_param_check(char_descr_val, control);
|
||||
if (status != ESP_OK){
|
||||
return status;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_SET_ATTR_VALUE;
|
||||
arg.set_attr_val.handle = attr_handle;
|
||||
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_gatt_status_t esp_ble_gatts_get_attr_value(uint16_t attr_handle, uint16_t *length, const uint8_t **value)
|
||||
{
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (attr_handle == ESP_GATT_ILLEGAL_HANDLE) {
|
||||
return ESP_GATT_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
return btc_gatts_get_attr_value(attr_handle, length, (uint8_t **)value);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
static esp_err_t esp_ble_gatts_add_char_desc_param_check(esp_attr_value_t *char_val, esp_attr_control_t *control)
|
||||
{
|
||||
if ((control != NULL) && ((control->auto_rsp != ESP_GATT_AUTO_RSP) && (control->auto_rsp != ESP_GATT_RSP_BY_APP))){
|
||||
LOG_ERROR("Error in %s, line=%d, control->auto_rsp should be set to ESP_GATT_AUTO_RSP or ESP_GATT_RSP_BY_APP\n",\
|
||||
__func__, __LINE__);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if ((control != NULL) && (control->auto_rsp == ESP_GATT_AUTO_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;
|
||||
}
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#endif ///GATTS_INCLUDED
|
||||
216
components/bt/bluedroid/api/include/esp_a2dp_api.h
Normal file
216
components/bt/bluedroid/api/include/esp_a2dp_api.h
Normal file
@@ -0,0 +1,216 @@
|
||||
// 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_A2DP_API_H__
|
||||
#define __ESP_A2DP_API_H__
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_bt_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Media codec types supported by A2DP
|
||||
#define ESP_A2D_MCT_SBC (0) /*!< SBC */
|
||||
#define ESP_A2D_MCT_M12 (0x01) /*!< MPEG-1, 2 Audio */
|
||||
#define ESP_A2D_MCT_M24 (0x02) /*!< MPEG-2, 4 AAC */
|
||||
#define ESP_A2D_MCT_ATRAC (0x04) /*!< ATRAC family */
|
||||
#define ESP_A2D_MCT_NON_A2DP (0xff)
|
||||
|
||||
typedef uint8_t esp_a2d_mct_t;
|
||||
|
||||
/// A2DP media codec capabilities union
|
||||
typedef struct {
|
||||
esp_a2d_mct_t type; /*!< A2DP media codec type */
|
||||
#define ESP_A2D_CIE_LEN_SBC (4)
|
||||
#define ESP_A2D_CIE_LEN_M12 (4)
|
||||
#define ESP_A2D_CIE_LEN_M24 (6)
|
||||
#define ESP_A2D_CIE_LEN_ATRAC (7)
|
||||
union {
|
||||
uint8_t sbc[ESP_A2D_CIE_LEN_SBC];
|
||||
uint8_t m12[ESP_A2D_CIE_LEN_M12];
|
||||
uint8_t m24[ESP_A2D_CIE_LEN_M24];
|
||||
uint8_t atrac[ESP_A2D_CIE_LEN_ATRAC];
|
||||
} cie; /*!< A2DP codec information element */
|
||||
} __attribute__((packed)) esp_a2d_mcc_t;
|
||||
|
||||
/// Bluetooth A2DP connection states
|
||||
typedef enum {
|
||||
ESP_A2D_CONNECTION_STATE_DISCONNECTED = 0, /*!< connection released */
|
||||
ESP_A2D_CONNECTION_STATE_CONNECTING, /*!< connecting remote device */
|
||||
ESP_A2D_CONNECTION_STATE_CONNECTED, /*!< connection established */
|
||||
ESP_A2D_CONNECTION_STATE_DISCONNECTING /*!< disconnecting remote device */
|
||||
} esp_a2d_connection_state_t;
|
||||
|
||||
/// Bluetooth A2DP disconnection reason
|
||||
typedef enum {
|
||||
ESP_A2D_DISC_RSN_NORMAL = 0, /*!< Finished disconnection that is initiated by local or remote device */
|
||||
ESP_A2D_DISC_RSN_ABNORMAL /*!< Abnormal disconnection caused by signal loss */
|
||||
} esp_a2d_disc_rsn_t;
|
||||
|
||||
/// Bluetooth A2DP datapath states
|
||||
typedef enum {
|
||||
ESP_A2D_AUDIO_STATE_REMOTE_SUSPEND = 0, /*!< audio stream datapath suspended by remote device */
|
||||
ESP_A2D_AUDIO_STATE_STOPPED, /*!< audio stream datapath stopped */
|
||||
ESP_A2D_AUDIO_STATE_STARTED, /*!< audio stream datapath started */
|
||||
} esp_a2d_audio_state_t;
|
||||
|
||||
/// A2DP callback events
|
||||
typedef enum {
|
||||
ESP_A2D_CONNECTION_STATE_EVT = 0, /*!< connection state changed event */
|
||||
ESP_A2D_AUDIO_STATE_EVT = 1, /*!< audio stream transmission state changed event */
|
||||
ESP_A2D_AUDIO_CFG_EVT = 2 /*!< audio codec is configured */
|
||||
} esp_a2d_cb_event_t;
|
||||
|
||||
/// A2DP state callback parameters
|
||||
typedef union {
|
||||
/**
|
||||
* @brief ESP_A2D_CONNECTION_STATE_EVT
|
||||
*/
|
||||
struct a2d_conn_stat_param {
|
||||
esp_a2d_connection_state_t state; /*!< one of values from esp_a2d_connection_state_t */
|
||||
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
|
||||
esp_a2d_disc_rsn_t disc_rsn; /*!< reason of disconnection for "DISCONNECTED" */
|
||||
} conn_stat; /*!< A2DP connection status */
|
||||
|
||||
/**
|
||||
* @brief ESP_A2D_AUDIO_STATE_EVT
|
||||
*/
|
||||
struct a2d_audio_stat_param {
|
||||
esp_a2d_audio_state_t state; /*!< one of the values from esp_a2d_audio_state_t */
|
||||
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
|
||||
} audio_stat; /*!< audio stream playing state */
|
||||
|
||||
/**
|
||||
* @brief ESP_A2D_AUDIO_CFG_EVT
|
||||
*/
|
||||
struct a2d_audio_cfg_param {
|
||||
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
|
||||
esp_a2d_mcc_t mcc; /*!< A2DP media codec capability information */
|
||||
} audio_cfg; /*!< media codec configuration infomation */
|
||||
} esp_a2d_cb_param_t;
|
||||
|
||||
/**
|
||||
* @brief A2DP profile callback function type
|
||||
* @param event : Event type
|
||||
* @param param : Pointer to callback parameter
|
||||
*/
|
||||
typedef void (* esp_a2d_cb_t)(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param);
|
||||
|
||||
/**
|
||||
* @brief A2DP profile data callback function
|
||||
*
|
||||
* @param[in] buf : data received from A2DP source device and is PCM format decoder from SBC decoder;
|
||||
* buf references to a static memory block and can be overwritten by upcoming data
|
||||
*
|
||||
* @param[in] len : size(in bytes) in buf
|
||||
*
|
||||
*/
|
||||
typedef void (* esp_a2d_data_cb_t)(const uint8_t *buf, uint32_t len);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Register application callback function to A2DP module. This function should be called
|
||||
* only after esp_bluedroid_enable() completes successfully
|
||||
*
|
||||
* @param[in] callback: A2DP sink event callback function
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: if callback is a NULL function pointer
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_a2d_register_callback(esp_a2d_cb_t callback);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Register A2DP sink data output function; For now the output is PCM data stream decoded
|
||||
* from SBC format. This function should be called only after esp_bluedroid_enable()
|
||||
* completes successfully
|
||||
*
|
||||
* @param[in] callback: A2DP data callback function
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: if callback is a NULL function pointer
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_a2d_register_data_callback(esp_a2d_data_cb_t callback);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Initialize the bluetooth A2DP sink module. This function should be called
|
||||
* after esp_bluedroid_enable() completes successfully
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: if the initialization request is sent successfully
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_a2d_sink_init(void);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief De-initialize for A2DP sink module. This function
|
||||
* should be called only after esp_bluedroid_enable() completes successfully
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_a2d_sink_deinit(void);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Connect the remote bluetooth device bluetooth, must after esp_a2d_sink_init()
|
||||
*
|
||||
* @param[in] remote_bda: remote bluetooth device address
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: connect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_a2d_sink_connect(esp_bd_addr_t remote_bda);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Disconnect the remote bluetooth device
|
||||
*
|
||||
* @param[in] remote_bda: remote bluetooth device address
|
||||
* @return
|
||||
* - ESP_OK: disconnect request is sent to lower layer
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_a2d_sink_disconnect(esp_bd_addr_t remote_bda);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __ESP_A2DP_API_H__ */
|
||||
153
components/bt/bluedroid/api/include/esp_avrc_api.h
Normal file
153
components/bt/bluedroid/api/include/esp_avrc_api.h
Normal file
@@ -0,0 +1,153 @@
|
||||
// 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_AVRC_API_H__
|
||||
#define __ESP_AVRC_API_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_bt_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// AVRC feature bit mask
|
||||
typedef enum {
|
||||
ESP_AVRC_FEAT_RCTG = 0x0001, /*!< remote control target */
|
||||
ESP_AVRC_FEAT_RCCT = 0x0002, /*!< remote control controller */
|
||||
ESP_AVRC_FEAT_VENDOR = 0x0008, /*!< remote control vendor dependent commands */
|
||||
ESP_AVRC_FEAT_BROWSE = 0x0010, /*!< use browsing channel */
|
||||
ESP_AVRC_FEAT_META_DATA = 0x0040, /*!< remote control metadata transfer command/response */
|
||||
ESP_AVRC_FEAT_ADV_CTRL = 0x0200, /*!< remote control advanced control commmand/response */
|
||||
} esp_avrc_features_t;
|
||||
|
||||
/// AVRC passthrough command code
|
||||
typedef enum {
|
||||
ESP_AVRC_PT_CMD_PLAY = 0x44, /*!< play */
|
||||
ESP_AVRC_PT_CMD_STOP = 0x45, /*!< stop */
|
||||
ESP_AVRC_PT_CMD_PAUSE = 0x46, /*!< pause */
|
||||
ESP_AVRC_PT_CMD_FORWARD = 0x4B, /*!< forward */
|
||||
ESP_AVRC_PT_CMD_BACKWARD = 0x4C /*!< backward */
|
||||
} esp_avrc_pt_cmd_t;
|
||||
|
||||
/// AVRC passthrough command state
|
||||
typedef enum {
|
||||
ESP_AVRC_PT_CMD_STATE_PRESSED = 0, /*!< key pressed */
|
||||
ESP_AVRC_PT_CMD_STATE_RELEASED = 1 /*!< key released */
|
||||
} esp_avrc_pt_cmd_state_t;
|
||||
|
||||
/// AVRC Controller callback events
|
||||
typedef enum {
|
||||
ESP_AVRC_CT_CONNECTION_STATE_EVT = 0, /*!< connection state changed event */
|
||||
ESP_AVRC_CT_PASSTHROUGH_RSP_EVT = 1, /*!< passthrough response event */
|
||||
ESP_AVRC_CT_MAX_EVT
|
||||
} esp_avrc_ct_cb_event_t;
|
||||
|
||||
/// AVRC controller callback parameters
|
||||
typedef union {
|
||||
/**
|
||||
* @brief ESP_AVRC_CT_CONNECTION_STATE_EVT
|
||||
*/
|
||||
struct avrc_ct_conn_stat_param {
|
||||
bool connected; /*!< whether AVRC connection is set up */
|
||||
uint32_t feat_mask; /*!< AVRC feature mask of remote device */
|
||||
esp_bd_addr_t remote_bda; /*!< remote bluetooth device address */
|
||||
} conn_stat; /*!< AVRC connection status */
|
||||
|
||||
/**
|
||||
* @brief ESP_AVRC_CT_PASSTHROUGH_RSP_EVT
|
||||
*/
|
||||
struct avrc_ct_psth_rsp_param {
|
||||
uint8_t tl; /*!< transaction label, 0 to 15 */
|
||||
uint8_t key_code; /*!< passthrough command code */
|
||||
uint8_t key_state; /*!< 0 for PRESSED, 1 for RELEASED */
|
||||
} psth_rsp; /*!< passthrough command response */
|
||||
} esp_avrc_ct_cb_param_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief AVRCP controller callback function type
|
||||
* @param event : Event type
|
||||
* @param param : Pointer to callback parameter union
|
||||
*/
|
||||
typedef void (* esp_avrc_ct_cb_t)(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Register application callbacks to AVRCP module; for now only AVRCP Controller
|
||||
* role is supported. This function should be called after esp_bluedroid_enable()
|
||||
* completes successfully
|
||||
*
|
||||
* @param[in] callback: AVRCP controller callback function
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_register_callback(esp_avrc_ct_cb_t callback);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief Initialize the bluetooth AVRCP controller module, This function should be called
|
||||
* after esp_bluedroid_enable() completes successfully
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_init(void);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief De-initialize AVRCP controller module. This function should be called after
|
||||
* after esp_bluedroid_enable() completes successfully
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_deinit(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Send passthrough command to AVRCP target, This function should be called after
|
||||
* ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established
|
||||
*
|
||||
* @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values.
|
||||
* @param[in] key_code : passthrough command code, e.g. ESP_AVRC_PT_CMD_PLAY, ESP_AVRC_PT_CMD_STOP, etc.
|
||||
* @param[in] key_state : passthrough command key state, ESP_AVRC_PT_CMD_STATE_PRESSED or
|
||||
* ESP_AVRC_PT_CMD_STATE_PRESSED
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t key_state);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_AVRC_API_H__ */
|
||||
375
components/bt/bluedroid/api/include/esp_blufi_api.h
Normal file
375
components/bt/bluedroid/api/include/esp_blufi_api.h
Normal file
@@ -0,0 +1,375 @@
|
||||
// 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_EVENT_RECV_SLAVE_DISCONNECT_BLE, /*<! When Phone send Disconnect 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 */
|
||||
uint8_t server_if; /*!< server interface */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
} 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);
|
||||
|
||||
/**
|
||||
* @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_blufi_close(esp_gatt_if_t gatts_if, uint16_t conn_id);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ESP_BLUFI_API_ */
|
||||
131
components/bt/bluedroid/api/include/esp_bt_defs.h
Normal file
131
components/bt/bluedroid/api/include/esp_bt_defs.h
Normal file
@@ -0,0 +1,131 @@
|
||||
// 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
|
||||
|
||||
#define ESP_BLUEDROID_STATUS_CHECK(status) \
|
||||
if (esp_bluedroid_get_status() != (status)) { \
|
||||
return ESP_ERR_INVALID_STATE; \
|
||||
}
|
||||
|
||||
|
||||
/* relate to BT_STATUS_xxx in bt_def.h */
|
||||
/// Status Return Value
|
||||
typedef enum {
|
||||
ESP_BT_STATUS_SUCCESS = 0, /* relate to BT_STATUS_SUCCESS in bt_def.h */
|
||||
ESP_BT_STATUS_FAIL, /* relate to BT_STATUS_FAIL in bt_def.h */
|
||||
ESP_BT_STATUS_NOT_READY, /* relate to BT_STATUS_NOT_READY in bt_def.h */
|
||||
ESP_BT_STATUS_NOMEM, /* relate to BT_STATUS_NOMEM in bt_def.h */
|
||||
ESP_BT_STATUS_BUSY, /* relate to BT_STATUS_BUSY in bt_def.h */
|
||||
ESP_BT_STATUS_DONE = 5, /* relate to BT_STATUS_DONE in bt_def.h */
|
||||
ESP_BT_STATUS_UNSUPPORTED, /* relate to BT_STATUS_UNSUPPORTED in bt_def.h */
|
||||
ESP_BT_STATUS_PARM_INVALID, /* relate to BT_STATUS_PARM_INVALID in bt_def.h */
|
||||
ESP_BT_STATUS_UNHANDLED, /* relate to BT_STATUS_UNHANDLED in bt_def.h */
|
||||
ESP_BT_STATUS_AUTH_FAILURE, /* relate to BT_STATUS_AUTH_FAILURE in bt_def.h */
|
||||
ESP_BT_STATUS_RMT_DEV_DOWN = 10, /* relate to BT_STATUS_RMT_DEV_DOWN in bt_def.h */
|
||||
ESP_BT_STATUS_AUTH_REJECTED, /* relate to BT_STATUS_AUTH_REJECTED in bt_def.h */
|
||||
ESP_BT_STATUS_INVALID_STATIC_RAND_ADDR, /* relate to BT_STATUS_INVALID_STATIC_RAND_ADDR in bt_def.h */
|
||||
ESP_BT_STATUS_PENDING, /* relate to BT_STATUS_PENDING in bt_def.h */
|
||||
ESP_BT_STATUS_UNACCEPT_CONN_INTERVAL, /* relate to BT_UNACCEPT_CONN_INTERVAL in bt_def.h */
|
||||
ESP_BT_STATUS_PARAM_OUT_OF_RANGE, /* relate to BT_PARAM_OUT_OF_RANGE in bt_def.h */
|
||||
ESP_BT_STATUS_TIMEOUT, /* relate to BT_STATUS_TIMEOUT in bt_def.h */
|
||||
ESP_BT_STATUS_PEER_LE_DATA_LEN_UNSUPPORTED, /* relate to BTM_PEER_LE_DATA_LEN_UNSUPPORTED in btm_api.h */
|
||||
ESP_BT_STATUS_CONTROL_LE_DATA_LEN_UNSUPPORTED,/* relate to BTM_CONTROL_LE_DATA_LEN_UNSUPPORTED in btm_api.h */
|
||||
ESP_BT_STATUS_ERR_ILLEGAL_PARAMETER_FMT, /* relate to HCI_ERR_ILLEGAL_PARAMETER_FMT in hcidefs.h */
|
||||
} esp_bt_status_t;
|
||||
|
||||
|
||||
/*Define the bt octet 16 bit size*/
|
||||
#define ESP_BT_OCTET16_LEN 16
|
||||
typedef uint8_t esp_bt_octet16_t[ESP_BT_OCTET16_LEN]; /* octet array: size 16 */
|
||||
|
||||
#define ESP_BT_OCTET8_LEN 8
|
||||
typedef uint8_t esp_bt_octet8_t[ESP_BT_OCTET8_LEN]; /* octet array: size 8 */
|
||||
|
||||
typedef uint8_t esp_link_key[ESP_BT_OCTET16_LEN]; /* Link Key */
|
||||
|
||||
/// 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];
|
||||
|
||||
/// 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;
|
||||
|
||||
/// Used to exchange the encrytyption key in the init key & response key
|
||||
#define ESP_BLE_ENC_KEY_MASK (1 << 0) /* relate to BTM_BLE_ENC_KEY_MASK in btm_api.h */
|
||||
/// Used to exchange the IRK key in the init key & response key
|
||||
#define ESP_BLE_ID_KEY_MASK (1 << 1) /* relate to BTM_BLE_ID_KEY_MASK in btm_api.h */
|
||||
/// Used to exchange the CSRK key in the init key & response key
|
||||
#define ESP_BLE_CSR_KEY_MASK (1 << 2) /* relate to BTM_BLE_CSR_KEY_MASK in btm_api.h */
|
||||
/// Used to exchange the link key(this key just used in the BLE & BR/EDR coexist mode) in the init key & response key
|
||||
#define ESP_BLE_LINK_KEY_MASK (1 << 3) /* relate to BTM_BLE_LINK_KEY_MASK in btm_api.h */
|
||||
typedef uint8_t esp_ble_key_mask_t; /* the key mask type */
|
||||
|
||||
/// 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__ */
|
||||
55
components/bt/bluedroid/api/include/esp_bt_device.h
Normal file
55
components/bt/bluedroid/api/include/esp_bt_device.h
Normal file
@@ -0,0 +1,55 @@
|
||||
// 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_DEVICE_H__
|
||||
#define __ESP_BT_DEVICE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_bt_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
*
|
||||
* @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);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set bluetooth device name. This function should be called after esp_bluedroid_enable()
|
||||
* completes successfully
|
||||
*
|
||||
* @param[in] name : device name to be set
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Succeed
|
||||
* - ESP_ERR_INVALID_ARG : if name is NULL pointer or empty, or string length out of limit
|
||||
* - ESP_INVALID_STATE : if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL : others
|
||||
*/
|
||||
esp_err_t esp_bt_dev_set_device_name(const char *name);
|
||||
|
||||
#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__ */
|
||||
906
components/bt/bluedroid/api/include/esp_gap_ble_api.h
Normal file
906
components/bt/bluedroid/api/include/esp_gap_ble_api.h
Normal file
@@ -0,0 +1,906 @@
|
||||
// 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 )
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* relate to BTM_LE_KEY_xxx in btm_api.h */
|
||||
#define ESP_LE_KEY_NONE 0 /* relate to BTM_LE_KEY_NONE in btm_api.h */
|
||||
#define ESP_LE_KEY_PENC (1 << 0) /*!< encryption key, encryption information of peer device */ /* relate to BTM_LE_KEY_PENC in btm_api.h */
|
||||
#define ESP_LE_KEY_PID (1 << 1) /*!< identity key of the peer device */ /* relate to BTM_LE_KEY_PID in btm_api.h */
|
||||
#define ESP_LE_KEY_PCSRK (1 << 2) /*!< peer SRK */ /* relate to BTM_LE_KEY_PCSRK in btm_api.h */
|
||||
#define ESP_LE_KEY_PLK (1 << 3) /*!< Link key*/ /* relate to BTM_LE_KEY_PLK in btm_api.h */
|
||||
#define ESP_LE_KEY_LLK (ESP_LE_KEY_PLK << 4) /* relate to BTM_LE_KEY_LLK in btm_api.h */
|
||||
#define ESP_LE_KEY_LENC (ESP_LE_KEY_PENC << 4) /*!< master role security information:div */ /* relate to BTM_LE_KEY_LENC in btm_api.h */
|
||||
#define ESP_LE_KEY_LID (ESP_LE_KEY_PID << 4) /*!< master device ID key */ /* relate to BTM_LE_KEY_LID in btm_api.h */
|
||||
#define ESP_LE_KEY_LCSRK (ESP_LE_KEY_PCSRK << 4) /*!< local CSRK has been deliver to peer */ /* relate to BTM_LE_KEY_LCSRK in btm_api.h */
|
||||
typedef uint8_t esp_ble_key_type_t;
|
||||
|
||||
/* relate to BTM_LE_AUTH_xxx in btm_api.h */
|
||||
#define ESP_LE_AUTH_NO_BOND 0x00 /*!< 0*/ /* relate to BTM_LE_AUTH_NO_BOND in btm_api.h */
|
||||
#define ESP_LE_AUTH_BOND 0x01 /*!< 1 << 0 */ /* relate to BTM_LE_AUTH_BOND in btm_api.h */
|
||||
#define ESP_LE_AUTH_REQ_MITM (1 << 2) /*!< 1 << 2 */ /* relate to BTM_LE_AUTH_REQ_MITM in btm_api.h */
|
||||
#define ESP_LE_AUTH_REQ_SC_ONLY (1 << 3) /*!< 1 << 3 */ /* relate to BTM_LE_AUTH_REQ_SC_ONLY in btm_api.h */
|
||||
#define ESP_LE_AUTH_REQ_SC_BOND (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_SC_ONLY) /*!< 1001 */ /* relate to BTM_LE_AUTH_REQ_SC_BOND in btm_api.h */
|
||||
#define ESP_LE_AUTH_REQ_SC_MITM (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY) /*!< 1100 */ /* relate to BTM_LE_AUTH_REQ_SC_MITM in btm_api.h */
|
||||
#define ESP_LE_AUTH_REQ_SC_MITM_BOND (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY | ESP_LE_AUTH_BOND) /*!< 1101 */ /* relate to BTM_LE_AUTH_REQ_SC_MITM_BOND in btm_api.h */
|
||||
typedef uint8_t esp_ble_auth_req_t; /*!< combination of the above bit pattern */
|
||||
|
||||
/* relate to BTM_IO_CAP_xxx in btm_api.h */
|
||||
#define ESP_IO_CAP_OUT 0 /*!< DisplayOnly */ /* relate to BTM_IO_CAP_OUT in btm_api.h */
|
||||
#define ESP_IO_CAP_IO 1 /*!< DisplayYesNo */ /* relate to BTM_IO_CAP_IO in btm_api.h */
|
||||
#define ESP_IO_CAP_IN 2 /*!< KeyboardOnly */ /* relate to BTM_IO_CAP_IN in btm_api.h */
|
||||
#define ESP_IO_CAP_NONE 3 /*!< NoInputNoOutput */ /* relate to BTM_IO_CAP_NONE in btm_api.h */
|
||||
#define ESP_IO_CAP_KBDISP 4 /*!< Keyboard display */ /* relate to BTM_IO_CAP_KBDISP in btm_api.h */
|
||||
typedef uint8_t esp_ble_io_cap_t; /*!< combination of the io capability */
|
||||
|
||||
|
||||
/// 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_AUTH_CMPL_EVT, /* Authentication complete indication. */
|
||||
ESP_GAP_BLE_KEY_EVT, /* BLE key event for peer device keys */
|
||||
ESP_GAP_BLE_SEC_REQ_EVT, /* BLE security request */
|
||||
ESP_GAP_BLE_PASSKEY_NOTIF_EVT, /* passkey notification event */
|
||||
ESP_GAP_BLE_PASSKEY_REQ_EVT, /* passkey request event */
|
||||
ESP_GAP_BLE_OOB_REQ_EVT, /* OOB request event */
|
||||
ESP_GAP_BLE_LOCAL_IR_EVT, /* BLE local IR event */
|
||||
ESP_GAP_BLE_LOCAL_ER_EVT, /* BLE local ER event */
|
||||
ESP_GAP_BLE_NC_REQ_EVT, /* Numeric Comparison request event */
|
||||
ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT, /*!< When stop adv complete, the event comes */
|
||||
ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT, /*!< When stop scan complete, the event comes */
|
||||
ESP_GAP_BLE_SET_STATIC_RAND_ADDR_EVT, /*!< When set the static rand address complete, the event comes */
|
||||
ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT, /*!< When update connection parameters complete, the event comes */
|
||||
ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT, /*!< When set pkt lenght complete, the event comes */
|
||||
ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT, /*!< When Enable/disable privacy on the local device complete, the event comes */
|
||||
ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT, /*!< When remove the bond device complete, the event comes */
|
||||
ESP_GAP_BLE_EVT_MAX,
|
||||
} 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
|
||||
|
||||
/* relate to BTM_BLE_AD_TYPE_xxx in btm_ble_api.h */
|
||||
/// The type of advertising data(not adv_type)
|
||||
typedef enum {
|
||||
ESP_BLE_AD_TYPE_FLAG = 0x01, /* relate to BTM_BLE_AD_TYPE_FLAG in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_16SRV_PART = 0x02, /* relate to BTM_BLE_AD_TYPE_16SRV_PART in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_16SRV_CMPL = 0x03, /* relate to BTM_BLE_AD_TYPE_16SRV_CMPL in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_32SRV_PART = 0x04, /* relate to BTM_BLE_AD_TYPE_32SRV_PART in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_32SRV_CMPL = 0x05, /* relate to BTM_BLE_AD_TYPE_32SRV_CMPL in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_128SRV_PART = 0x06, /* relate to BTM_BLE_AD_TYPE_128SRV_PART in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_128SRV_CMPL = 0x07, /* relate to BTM_BLE_AD_TYPE_128SRV_CMPL in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_NAME_SHORT = 0x08, /* relate to BTM_BLE_AD_TYPE_NAME_SHORT in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_NAME_CMPL = 0x09, /* relate to BTM_BLE_AD_TYPE_NAME_CMPL in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_TX_PWR = 0x0A, /* relate to BTM_BLE_AD_TYPE_TX_PWR in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_DEV_CLASS = 0x0D, /* relate to BTM_BLE_AD_TYPE_DEV_CLASS in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_SM_TK = 0x10, /* relate to BTM_BLE_AD_TYPE_SM_TK in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_SM_OOB_FLAG = 0x11, /* relate to BTM_BLE_AD_TYPE_SM_OOB_FLAG in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_INT_RANGE = 0x12, /* relate to BTM_BLE_AD_TYPE_INT_RANGE in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_SOL_SRV_UUID = 0x14, /* relate to BTM_BLE_AD_TYPE_SOL_SRV_UUID in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_128SOL_SRV_UUID = 0x15, /* relate to BTM_BLE_AD_TYPE_128SOL_SRV_UUID in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_SERVICE_DATA = 0x16, /* relate to BTM_BLE_AD_TYPE_SERVICE_DATA in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_PUBLIC_TARGET = 0x17, /* relate to BTM_BLE_AD_TYPE_PUBLIC_TARGET in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_RANDOM_TARGET = 0x18, /* relate to BTM_BLE_AD_TYPE_RANDOM_TARGET in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_APPEARANCE = 0x19, /* relate to BTM_BLE_AD_TYPE_APPEARANCE in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_ADV_INT = 0x1A, /* relate to BTM_BLE_AD_TYPE_ADV_INT in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_LE_DEV_ADDR = 0x1b, /* relate to BTM_BLE_AD_TYPE_LE_DEV_ADDR in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_LE_ROLE = 0x1c, /* relate to BTM_BLE_AD_TYPE_LE_ROLE in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_SPAIR_C256 = 0x1d, /* relate to BTM_BLE_AD_TYPE_SPAIR_C256 in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_SPAIR_R256 = 0x1e, /* relate to BTM_BLE_AD_TYPE_SPAIR_R256 in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_32SOL_SRV_UUID = 0x1f, /* relate to BTM_BLE_AD_TYPE_32SOL_SRV_UUID in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_32SERVICE_DATA = 0x20, /* relate to BTM_BLE_AD_TYPE_32SERVICE_DATA in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_128SERVICE_DATA = 0x21, /* relate to BTM_BLE_AD_TYPE_128SERVICE_DATA in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_LE_SECURE_CONFIRM = 0x22, /* relate to BTM_BLE_AD_TYPE_LE_SECURE_CONFIRM in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_LE_SECURE_RANDOM = 0x23, /* relate to BTM_BLE_AD_TYPE_LE_SECURE_RANDOM in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_URI = 0x24, /* relate to BTM_BLE_AD_TYPE_URI in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_INDOOR_POSITION = 0x25, /* relate to BTM_BLE_AD_TYPE_INDOOR_POSITION in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_TRANS_DISC_DATA = 0x26, /* relate to BTM_BLE_AD_TYPE_TRANS_DISC_DATA in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_LE_SUPPORT_FEATURE = 0x27, /* relate to BTM_BLE_AD_TYPE_LE_SUPPORT_FEATURE in btm_ble_api.h */
|
||||
ESP_BLE_AD_TYPE_CHAN_MAP_UPDATE = 0x28, /* relate to BTM_BLE_AD_TYPE_CHAN_MAP_UPDATE in btm_ble_api.h */
|
||||
ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE = 0xFF, /* relate to BTM_BLE_AD_MANUFACTURER_SPECIFIC_TYPE in btm_ble_api.h */
|
||||
} 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;
|
||||
|
||||
|
||||
/* relate to BTA_DM_BLE_SEC_xxx in bta_api.h */
|
||||
typedef enum {
|
||||
ESP_BLE_SEC_NONE = 0, /* relate to BTA_DM_BLE_SEC_NONE in bta_api.h */
|
||||
ESP_BLE_SEC_ENCRYPT, /* relate to BTA_DM_BLE_SEC_ENCRYPT in bta_api.h */
|
||||
ESP_BLE_SEC_ENCRYPT_NO_MITM, /* relate to BTA_DM_BLE_SEC_ENCRYPT_NO_MITM in bta_api.h */
|
||||
ESP_BLE_SEC_ENCRYPT_MITM, /* relate to BTA_DM_BLE_SEC_ENCRYPT_MITM in bta_api.h */
|
||||
}esp_ble_sec_act_t;
|
||||
|
||||
typedef enum {
|
||||
ESP_BLE_SM_PASSKEY = 0,
|
||||
ESP_BLE_SM_AUTHEN_REQ_MODE,
|
||||
ESP_BLE_SM_IOCAP_MODE,
|
||||
ESP_BLE_SM_SET_INIT_KEY,
|
||||
ESP_BLE_SM_SET_RSP_KEY,
|
||||
ESP_BLE_SM_MAX_KEY_SIZE,
|
||||
} esp_ble_sm_param_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;
|
||||
|
||||
/// 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;
|
||||
|
||||
/**
|
||||
* @brief BLE pkt date length keys
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t rx_len; /*!< pkt rx data length value */
|
||||
uint16_t tx_len; /*!< pkt tx data length value */
|
||||
}esp_ble_pkt_data_length_params_t;
|
||||
|
||||
/**
|
||||
* @brief BLE encryption keys
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
esp_bt_octet16_t ltk; /*!< The long term key*/
|
||||
esp_bt_octet8_t rand; /*!< The random number*/
|
||||
uint16_t ediv; /*!< The ediv value*/
|
||||
uint8_t sec_level; /*!< The security level of the security link*/
|
||||
uint8_t key_size; /*!< The key size(7~16) of the security link*/
|
||||
} esp_ble_penc_keys_t; /*!< The key type*/
|
||||
|
||||
/**
|
||||
* @brief BLE CSRK keys
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t counter; /*!< The counter */
|
||||
esp_bt_octet16_t csrk; /*!< The csrk key */
|
||||
uint8_t sec_level; /*!< The security level */
|
||||
} esp_ble_pcsrk_keys_t; /*!< The pcsrk key type */
|
||||
|
||||
/**
|
||||
* @brief BLE pid keys
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
esp_bt_octet16_t irk; /*!< The irk value */
|
||||
esp_ble_addr_type_t addr_type; /*!< The address type */
|
||||
esp_bd_addr_t static_addr; /*!< The static address */
|
||||
} esp_ble_pid_keys_t; /*!< The pid key type */
|
||||
|
||||
/**
|
||||
* @brief BLE Encryption reproduction keys
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
esp_bt_octet16_t ltk; /*!< The long term key */
|
||||
uint16_t div; /*!< The div value */
|
||||
uint8_t key_size; /*!< The key size of the security link */
|
||||
uint8_t sec_level; /*!< The security level of the security link */
|
||||
} esp_ble_lenc_keys_t; /*!< The key type */
|
||||
|
||||
/**
|
||||
* @brief BLE SRK keys
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t counter; /*!< The counter value */
|
||||
uint16_t div; /*!< The div value */
|
||||
uint8_t sec_level; /*!< The security level of the security link */
|
||||
esp_bt_octet16_t csrk; /*!< The csrk key value */
|
||||
} esp_ble_lcsrk_keys; /*!< The csrk key type */
|
||||
|
||||
/**
|
||||
* @brief Structure associated with ESP_KEY_NOTIF_EVT
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
esp_bd_addr_t bd_addr; /*!< peer address */
|
||||
uint32_t passkey; /*!< the numeric value for comparison. If just_works, do not show this number to UI */
|
||||
} esp_ble_sec_key_notif_t; /*!< BLE key notify type*/
|
||||
|
||||
/**
|
||||
* @brief Structure of the security request
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
esp_bd_addr_t bd_addr; /*!< peer address */
|
||||
} esp_ble_sec_req_t; /*!< BLE security request type*/
|
||||
|
||||
/**
|
||||
* @brief union type of the security key value
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
esp_ble_penc_keys_t penc_key; /*!< received peer encryption key */
|
||||
esp_ble_pcsrk_keys_t pcsrk_key; /*!< received peer device SRK */
|
||||
esp_ble_pid_keys_t pid_key; /*!< peer device ID key */
|
||||
esp_ble_lenc_keys_t lenc_key; /*!< local encryption reproduction keys LTK = = d1(ER,DIV,0)*/
|
||||
esp_ble_lcsrk_keys lcsrk_key; /*!< local device CSRK = d1(ER,DIV,1)*/
|
||||
} esp_ble_key_value_t; /*!< ble key value type*/
|
||||
|
||||
/**
|
||||
* @brief struct type of the bond key informatuon value
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
esp_ble_key_mask_t key_mask; /*!< the key mask to indicate witch key is present */
|
||||
esp_ble_penc_keys_t penc_key; /*!< received peer encryption key */
|
||||
esp_ble_pcsrk_keys_t pcsrk_key; /*!< received peer device SRK */
|
||||
esp_ble_pid_keys_t pid_key; /*!< peer device ID key */
|
||||
} esp_ble_bond_key_info_t; /*!< ble bond key information value type */
|
||||
|
||||
/**
|
||||
* @brief struct type of the bond device value
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
esp_bd_addr_t bd_addr; /*!< peer address */
|
||||
esp_ble_bond_key_info_t bond_key; /*!< the bond key information */
|
||||
} esp_ble_bond_dev_t; /*!< the ble bond device type */
|
||||
|
||||
|
||||
/**
|
||||
* @brief union type of the security key value
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
esp_bd_addr_t bd_addr; /*!< peer address */
|
||||
esp_ble_key_type_t key_type; /*!< key type of the security link */
|
||||
esp_ble_key_value_t p_key_value; /*!< the pointer to the key value */
|
||||
} esp_ble_key_t; /*!< the union to the ble key value type*/
|
||||
|
||||
/**
|
||||
* @brief structure type of the ble local id keys value
|
||||
*/
|
||||
typedef struct {
|
||||
esp_bt_octet16_t ir; /*!< the 16 bits of the ir value */
|
||||
esp_bt_octet16_t irk; /*!< the 16 bits of the ir key value */
|
||||
esp_bt_octet16_t dhk; /*!< the 16 bits of the dh key value */
|
||||
} esp_ble_local_id_keys_t; /*!< the structure of the ble local id keys value type*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Structure associated with ESP_AUTH_CMPL_EVT
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
esp_bd_addr_t bd_addr; /*!< BD address peer device. */
|
||||
bool key_present; /*!< Valid link key value in key element */
|
||||
esp_link_key key; /*!< Link key associated with peer device. */
|
||||
uint8_t key_type; /*!< The type of Link Key */
|
||||
bool success; /*!< TRUE of authentication succeeded, FALSE if failed. */
|
||||
uint8_t fail_reason; /*!< The HCI reason/error code for when success=FALSE */
|
||||
esp_ble_addr_type_t addr_type; /*!< Peer device address type */
|
||||
esp_bt_dev_type_t dev_type; /*!< Device type */
|
||||
} esp_ble_auth_cmpl_t; /*!< The ble authentication complite cb type */
|
||||
|
||||
/**
|
||||
* @brief union associated with ble security
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
esp_ble_sec_key_notif_t key_notif; /*!< passkey notification */
|
||||
esp_ble_sec_req_t ble_req; /*!< BLE SMP related request */
|
||||
esp_ble_key_t ble_key; /*!< BLE SMP keys used when pairing */
|
||||
esp_ble_local_id_keys_t ble_id_keys; /*!< BLE IR event */
|
||||
esp_ble_auth_cmpl_t auth_cmpl; /*!< Authentication complete indication. */
|
||||
} esp_ble_sec_t; /*!< Ble secutity type */
|
||||
|
||||
/// 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 */
|
||||
uint8_t adv_data_len; /*!< Adv data length */
|
||||
uint8_t scan_rsp_len; /*!< Scan response length */
|
||||
} 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_sec_t ble_security; /*!< ble gap security union type */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT
|
||||
*/
|
||||
struct ble_scan_stop_cmpl_evt_param {
|
||||
esp_bt_status_t status; /*!< Indicate scan stop operation success status */
|
||||
} scan_stop_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_STOP_COMPLETE_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT
|
||||
*/
|
||||
struct ble_adv_stop_cmpl_evt_param {
|
||||
esp_bt_status_t status; /*!< Indicate adv stop operation success status */
|
||||
} adv_stop_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_STOP_COMPLETE_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_SET_STATIC_RAND_ADDR_EVT
|
||||
*/
|
||||
struct ble_set_rand_cmpl_evt_param {
|
||||
esp_bt_status_t status; /*!< Indicate set static rand address operation success status */
|
||||
} set_rand_addr_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_STATIC_RAND_ADDR_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT
|
||||
*/
|
||||
struct ble_update_conn_params_evt_param {
|
||||
esp_bt_status_t status; /*!< Indicate update connection parameters success status */
|
||||
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 conn_int; /*!< Current connection interval */
|
||||
uint16_t timeout; /*!< Supervision timeout for the LE Link. Range: 0x000A to 0x0C80.
|
||||
Mandatory Range: 0x000A to 0x0C80 Time = N * 10 msec */
|
||||
}update_conn_params; /*!< Event parameter of ESP_GAP_BLE_UPDATE_CONN_PARAMS_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT
|
||||
*/
|
||||
struct ble_pkt_data_length_cmpl_evt_param {
|
||||
esp_bt_status_t status; /*!< Indicate the set pkt data length operation success status */
|
||||
esp_ble_pkt_data_length_params_t params; /*!< pkt data length value */
|
||||
} pkt_data_lenth_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_PKT_LENGTH_COMPLETE_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT
|
||||
*/
|
||||
struct ble_local_privacy_cmpl_evt_param {
|
||||
esp_bt_status_t status; /*!< Indicate the set local privacy operation success status */
|
||||
} local_privacy_cmpl; /*!< Event parameter of ESP_GAP_BLE_SET_LOCAL_PRIVACY_COMPLETE_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_REMOVE_BOND_DEV_COMPLETE_EVT
|
||||
*/
|
||||
struct ble_remove_bond_dev_cmpl_evt_param {
|
||||
esp_bt_status_t status; /*!< Indicate the remove bond device operation success status */
|
||||
esp_bd_addr_t bd_addr; /*!< The device address which has been remove from the bond list */
|
||||
}remove_bond_dev_cmpl; /*!< Event parameter of ESP_GAP_BLE_REMOVE_BOND_DEV_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);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set a GAP security parameter value. Overrides the default value.
|
||||
*
|
||||
* @param[in] param_type :L the type of the param which to be set
|
||||
* @param[in] value : the param value
|
||||
* @param[out] len : the length of the param value
|
||||
*
|
||||
* @return - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gap_set_security_param(esp_ble_sm_param_t param_type,
|
||||
void *value, uint8_t len);
|
||||
|
||||
/**
|
||||
* @brief Grant security request access.
|
||||
*
|
||||
* @param[in] bd_addr : BD address of the peer
|
||||
* @param[in] accept : accept the security request or not
|
||||
*
|
||||
* @return - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gap_security_rsp(esp_bd_addr_t bd_addr, bool accept);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set a gap parameter value. Use this function to change
|
||||
* the default GAP parameter values.
|
||||
*
|
||||
* @param[in] bd_addr : the address of the peer device need to encryption
|
||||
* @param[in] sec_act : This is the security action to indicate
|
||||
* what kind of BLE security level is required for
|
||||
* the BLE link if the BLE is supported
|
||||
*
|
||||
* @return - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_set_encryption(esp_bd_addr_t bd_addr, esp_ble_sec_act_t sec_act);
|
||||
|
||||
/**
|
||||
* @brief Reply the key value to the peer device in the lagecy connection stage.
|
||||
*
|
||||
* @param[in] bd_addr : BD address of the peer
|
||||
* @param[in] accept : passkey entry sucessful or declined.
|
||||
* @param[in] passkey : passkey value, must be a 6 digit number,
|
||||
* can be lead by 0.
|
||||
*
|
||||
* @return - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t passkey);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Reply the comfirm value to the peer device in the lagecy connection stage.
|
||||
*
|
||||
* @param[in] bd_addr : BD address of the peer device
|
||||
* @param[in] accept : numbers to compare are the same or different.
|
||||
*
|
||||
* @return - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_confirm_reply(esp_bd_addr_t bd_addr, bool accept);
|
||||
|
||||
/**
|
||||
* @brief Removes a device from the security database list of
|
||||
* peer device. It manages unpairing event while connected.
|
||||
*
|
||||
* @param[in] bd_addr : BD address of the peer device
|
||||
*
|
||||
* @return - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_remove_bond_device(esp_bd_addr_t bd_addr);
|
||||
|
||||
/**
|
||||
* @brief Get the device number from the security database list of peer device.
|
||||
* It will return the device bonded number immediately.
|
||||
*
|
||||
* @return - >= 0 : bonded devices number.
|
||||
* - < 0 : failed
|
||||
*
|
||||
*/
|
||||
int esp_ble_get_bond_device_num(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the device from the security database list of peer device.
|
||||
* It will return the device bonded information immediately.
|
||||
* @param[inout] dev_num: Indicate the dev_list array(buffer) size as input.
|
||||
* If dev_num is large enough, it means the actual number as output.
|
||||
* Suggest that dev_num value equal to esp_ble_get_bond_device_num().
|
||||
*
|
||||
* @param[out] dev_list: an array(buffer) of `esp_ble_bond_dev_t` type. Use for storing the bonded devices address.
|
||||
* The dev_list should be allocated by who call this API.
|
||||
* @return - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_get_bond_device_list(int *dev_num, esp_ble_bond_dev_t *dev_list);
|
||||
|
||||
/**
|
||||
* @brief This function is to disconnect the physical connection of the peer device
|
||||
*
|
||||
* @param[in] remote_device : BD address of the peer device
|
||||
*
|
||||
* @return - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gap_disconnect(esp_bd_addr_t remote_device);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_GAP_BLE_API_H__ */
|
||||
52
components/bt/bluedroid/api/include/esp_gap_bt_api.h
Normal file
52
components/bt/bluedroid/api/include/esp_gap_bt_api.h
Normal file
@@ -0,0 +1,52 @@
|
||||
// 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_BT_API_H__
|
||||
#define __ESP_GAP_BT_API_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_bt_defs.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/// Discoverability and Connectability mode
|
||||
typedef enum {
|
||||
ESP_BT_SCAN_MODE_NONE = 0, /*!< Neither discoverable nor connectable */
|
||||
ESP_BT_SCAN_MODE_CONNECTABLE, /*!< Connectable but not discoverable */
|
||||
ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE /*!< both discoverable and connectaable */
|
||||
} esp_bt_scan_mode_t;
|
||||
|
||||
/**
|
||||
* @brief Set discoverability and connectability mode for legacy bluetooth. This function should
|
||||
* be called after esp_bluedroid_enable() completes successfully
|
||||
*
|
||||
* @param[in] mode : one of the enums of bt_scan_mode_t
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Succeed
|
||||
* - ESP_ERR_INVALID_ARG: if argument invalid
|
||||
* - ESP_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*/
|
||||
esp_err_t esp_bt_gap_set_scan_mode(esp_bt_scan_mode_t mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_GAP_BT_API_H__ */
|
||||
395
components/bt/bluedroid/api/include/esp_gatt_defs.h
Normal file
395
components/bt/bluedroid/api/include/esp_gatt_defs.h
Normal file
@@ -0,0 +1,395 @@
|
||||
// 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
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* relate to BTA_GATT_PREP_WRITE_xxx in bta_gatt_api.h */
|
||||
/// Attribute write data type from the client
|
||||
typedef enum {
|
||||
ESP_GATT_PREP_WRITE_CANCEL = 0x00, /*!< Prepare write cancel */ /* relate to BTA_GATT_PREP_WRITE_CANCEL in bta_gatt_api.h */
|
||||
ESP_GATT_PREP_WRITE_EXEC = 0x01, /*!< Prepare write execute */ /* relate to BTA_GATT_PREP_WRITE_EXEC in bta_gatt_api.h */
|
||||
} esp_gatt_prep_write_type;
|
||||
|
||||
/* relate to BTA_GATT_xxx in bta_gatt_api.h */
|
||||
/**
|
||||
* @brief GATT success code and error codes
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_GATT_OK = 0x0, /* relate to BTA_GATT_OK in bta_gatt_api.h */
|
||||
ESP_GATT_INVALID_HANDLE = 0x01, /* 0x0001 */ /* relate to BTA_GATT_INVALID_HANDLE in bta_gatt_api.h */
|
||||
ESP_GATT_READ_NOT_PERMIT = 0x02, /* 0x0002 */ /* relate to BTA_GATT_READ_NOT_PERMIT in bta_gatt_api.h */
|
||||
ESP_GATT_WRITE_NOT_PERMIT = 0x03, /* 0x0003 */ /* relate to BTA_GATT_WRITE_NOT_PERMIT in bta_gatt_api.h */
|
||||
ESP_GATT_INVALID_PDU = 0x04, /* 0x0004 */ /* relate to BTA_GATT_INVALID_PDU in bta_gatt_api.h */
|
||||
ESP_GATT_INSUF_AUTHENTICATION = 0x05, /* 0x0005 */ /* relate to BTA_GATT_INSUF_AUTHENTICATION in bta_gatt_api.h */
|
||||
ESP_GATT_REQ_NOT_SUPPORTED = 0x06, /* 0x0006 */ /* relate to BTA_GATT_REQ_NOT_SUPPORTED in bta_gatt_api.h */
|
||||
ESP_GATT_INVALID_OFFSET = 0x07, /* 0x0007 */ /* relate to BTA_GATT_INVALID_OFFSET in bta_gatt_api.h */
|
||||
ESP_GATT_INSUF_AUTHORIZATION = 0x08, /* 0x0008 */ /* relate to BTA_GATT_INSUF_AUTHORIZATION in bta_gatt_api.h */
|
||||
ESP_GATT_PREPARE_Q_FULL = 0x09, /* 0x0009 */ /* relate to BTA_GATT_PREPARE_Q_FULL in bta_gatt_api.h */
|
||||
ESP_GATT_NOT_FOUND = 0x0a, /* 0x000a */ /* relate to BTA_GATT_NOT_FOUND in bta_gatt_api.h */
|
||||
ESP_GATT_NOT_LONG = 0x0b, /* 0x000b */ /* relate to BTA_GATT_NOT_LONG in bta_gatt_api.h */
|
||||
ESP_GATT_INSUF_KEY_SIZE = 0x0c, /* 0x000c */ /* relate to BTA_GATT_INSUF_KEY_SIZE in bta_gatt_api.h */
|
||||
ESP_GATT_INVALID_ATTR_LEN = 0x0d, /* 0x000d */ /* relate to BTA_GATT_INVALID_ATTR_LEN in bta_gatt_api.h */
|
||||
ESP_GATT_ERR_UNLIKELY = 0x0e, /* 0x000e */ /* relate to BTA_GATT_ERR_UNLIKELY in bta_gatt_api.h */
|
||||
ESP_GATT_INSUF_ENCRYPTION = 0x0f, /* 0x000f */ /* relate to BTA_GATT_INSUF_ENCRYPTION in bta_gatt_api.h */
|
||||
ESP_GATT_UNSUPPORT_GRP_TYPE = 0x10, /* 0x0010 */ /* relate to BTA_GATT_UNSUPPORT_GRP_TYPE in bta_gatt_api.h */
|
||||
ESP_GATT_INSUF_RESOURCE = 0x11, /* 0x0011 */ /* relate to BTA_GATT_INSUF_RESOURCE in bta_gatt_api.h */
|
||||
|
||||
ESP_GATT_NO_RESOURCES = 0x80, /* 0x80 */ /* relate to BTA_GATT_NO_RESOURCES in bta_gatt_api.h */
|
||||
ESP_GATT_INTERNAL_ERROR = 0x81, /* 0x81 */ /* relate to BTA_GATT_INTERNAL_ERROR in bta_gatt_api.h */
|
||||
ESP_GATT_WRONG_STATE = 0x82, /* 0x82 */ /* relate to BTA_GATT_WRONG_STATE in bta_gatt_api.h */
|
||||
ESP_GATT_DB_FULL = 0x83, /* 0x83 */ /* relate to BTA_GATT_DB_FULL in bta_gatt_api.h */
|
||||
ESP_GATT_BUSY = 0x84, /* 0x84 */ /* relate to BTA_GATT_BUSY in bta_gatt_api.h */
|
||||
ESP_GATT_ERROR = 0x85, /* 0x85 */ /* relate to BTA_GATT_ERROR in bta_gatt_api.h */
|
||||
ESP_GATT_CMD_STARTED = 0x86, /* 0x86 */ /* relate to BTA_GATT_CMD_STARTED in bta_gatt_api.h */
|
||||
ESP_GATT_ILLEGAL_PARAMETER = 0x87, /* 0x87 */ /* relate to BTA_GATT_ILLEGAL_PARAMETER in bta_gatt_api.h */
|
||||
ESP_GATT_PENDING = 0x88, /* 0x88 */ /* relate to BTA_GATT_PENDING in bta_gatt_api.h */
|
||||
ESP_GATT_AUTH_FAIL = 0x89, /* 0x89 */ /* relate to BTA_GATT_AUTH_FAIL in bta_gatt_api.h */
|
||||
ESP_GATT_MORE = 0x8a, /* 0x8a */ /* relate to BTA_GATT_MORE in bta_gatt_api.h */
|
||||
ESP_GATT_INVALID_CFG = 0x8b, /* 0x8b */ /* relate to BTA_GATT_INVALID_CFG in bta_gatt_api.h */
|
||||
ESP_GATT_SERVICE_STARTED = 0x8c, /* 0x8c */ /* relate to BTA_GATT_SERVICE_STARTED in bta_gatt_api.h */
|
||||
ESP_GATT_ENCRYPED_MITM = ESP_GATT_OK, /* relate to BTA_GATT_ENCRYPED_MITM in bta_gatt_api.h */
|
||||
ESP_GATT_ENCRYPED_NO_MITM = 0x8d, /* 0x8d */ /* relate to BTA_GATT_ENCRYPED_NO_MITM in bta_gatt_api.h */
|
||||
ESP_GATT_NOT_ENCRYPTED = 0x8e, /* 0x8e */ /* relate to BTA_GATT_NOT_ENCRYPTED in bta_gatt_api.h */
|
||||
ESP_GATT_CONGESTED = 0x8f, /* 0x8f */ /* relate to BTA_GATT_CONGESTED in bta_gatt_api.h */
|
||||
ESP_GATT_DUP_REG = 0x90, /* 0x90 */ /* relate to BTA_GATT_DUP_REG in bta_gatt_api.h */
|
||||
ESP_GATT_ALREADY_OPEN = 0x91, /* 0x91 */ /* relate to BTA_GATT_ALREADY_OPEN in bta_gatt_api.h */
|
||||
ESP_GATT_CANCEL = 0x92, /* 0x92 */ /* relate to BTA_GATT_CANCEL in bta_gatt_api.h */
|
||||
/* 0xE0 ~ 0xFC reserved for future use */
|
||||
ESP_GATT_STACK_RSP = 0xe0, /* 0xe0 */ /* relate to BTA_GATT_STACK_RSP in bta_gatt_api.h */
|
||||
ESP_GATT_APP_RSP = 0xe1, /* 0xe1 */ /* relate to BTA_GATT_APP_RSP in bta_gatt_api.h */
|
||||
//Error caused by customer application or stack bug
|
||||
ESP_GATT_UNKNOWN_ERROR = 0xef, /* 0xef */ /* relate to BTA_GATT_UNKNOWN_ERROR in bta_gatt_api.h */
|
||||
ESP_GATT_CCC_CFG_ERR = 0xfd, /* 0xFD Client Characteristic Configuration Descriptor Improperly Configured */ /* relate to BTA_GATT_CCC_CFG_ERR in bta_gatt_api.h */
|
||||
ESP_GATT_PRC_IN_PROGRESS = 0xfe, /* 0xFE Procedure Already in progress */ /* relate to BTA_GATT_PRC_IN_PROGRESS in bta_gatt_api.h */
|
||||
ESP_GATT_OUT_OF_RANGE = 0xff, /* 0xFFAttribute value out of range */ /* relate to BTA_GATT_OUT_OF_RANGE in bta_gatt_api.h */
|
||||
} esp_gatt_status_t;
|
||||
|
||||
/* relate to BTA_GATT_CONN_xxx in bta_gatt_api.h */
|
||||
/**
|
||||
* @brief Gatt Connection reason enum
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_GATT_CONN_UNKNOWN = 0, /*!< Gatt connection unknown */ /* relate to BTA_GATT_CONN_UNKNOWN in bta_gatt_api.h */
|
||||
ESP_GATT_CONN_L2C_FAILURE = 1, /*!< General L2cap failure */ /* relate to BTA_GATT_CONN_L2C_FAILURE in bta_gatt_api.h */
|
||||
ESP_GATT_CONN_TIMEOUT = 0x08, /*!< Connection timeout */ /* relate to BTA_GATT_CONN_TIMEOUT in bta_gatt_api.h */
|
||||
ESP_GATT_CONN_TERMINATE_PEER_USER = 0x13, /*!< Connection terminate by peer user */ /* relate to BTA_GATT_CONN_TERMINATE_PEER_USER in bta_gatt_api.h */
|
||||
ESP_GATT_CONN_TERMINATE_LOCAL_HOST = 0x16, /*!< Connectionterminated by local host */ /* relate to BTA_GATT_CONN_TERMINATE_LOCAL_HOST in bta_gatt_api.h */
|
||||
ESP_GATT_CONN_FAIL_ESTABLISH = 0x3e, /*!< Connection fail to establish */ /* relate to BTA_GATT_CONN_FAIL_ESTABLISH in bta_gatt_api.h */
|
||||
ESP_GATT_CONN_LMP_TIMEOUT = 0x22, /*!< Connection fail for LMP response tout */ /* relate to BTA_GATT_CONN_LMP_TIMEOUT in bta_gatt_api.h */
|
||||
ESP_GATT_CONN_CONN_CANCEL = 0x0100, /*!< L2CAP connection cancelled */ /* relate to BTA_GATT_CONN_CONN_CANCEL in bta_gatt_api.h */
|
||||
ESP_GATT_CONN_NONE = 0x0101 /*!< No connection to cancel */ /* relate to BTA_GATT_CONN_NONE in bta_gatt_api.h */
|
||||
} 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;
|
||||
|
||||
/* relate to BTA_GATT_AUTH_REQ_xxx in bta_gatt_api.h */
|
||||
/**
|
||||
* @brief Gatt authentication request type
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_GATT_AUTH_REQ_NONE = 0, /* relate to BTA_GATT_AUTH_REQ_NONE in bta_gatt_api.h */
|
||||
ESP_GATT_AUTH_REQ_NO_MITM = 1, /* unauthenticated encryption */ /* relate to BTA_GATT_AUTH_REQ_NO_MITM in bta_gatt_api.h */
|
||||
ESP_GATT_AUTH_REQ_MITM = 2, /* authenticated encryption */ /* relate to BTA_GATT_AUTH_REQ_MITM in bta_gatt_api.h */
|
||||
ESP_GATT_AUTH_REQ_SIGNED_NO_MITM = 3, /* relate to BTA_GATT_AUTH_REQ_SIGNED_NO_MITM in bta_gatt_api.h */
|
||||
ESP_GATT_AUTH_REQ_SIGNED_MITM = 4, /* relate to BTA_GATT_AUTH_REQ_SIGNED_MITM in bta_gatt_api.h */
|
||||
} esp_gatt_auth_req_t;
|
||||
|
||||
/* relate to BTA_GATT_PERM_xxx in bta_gatt_api.h */
|
||||
/**
|
||||
* @brief Attribute permissions
|
||||
*/
|
||||
#define ESP_GATT_PERM_READ (1 << 0) /* bit 0 - 0x0001 */ /* relate to BTA_GATT_PERM_READ in bta_gatt_api.h */
|
||||
#define ESP_GATT_PERM_READ_ENCRYPTED (1 << 1) /* bit 1 - 0x0002 */ /* relate to BTA_GATT_PERM_READ_ENCRYPTED in bta_gatt_api.h */
|
||||
#define ESP_GATT_PERM_READ_ENC_MITM (1 << 2) /* bit 2 - 0x0004 */ /* relate to BTA_GATT_PERM_READ_ENC_MITM in bta_gatt_api.h */
|
||||
#define ESP_GATT_PERM_WRITE (1 << 4) /* bit 4 - 0x0010 */ /* relate to BTA_GATT_PERM_WRITE in bta_gatt_api.h */
|
||||
#define ESP_GATT_PERM_WRITE_ENCRYPTED (1 << 5) /* bit 5 - 0x0020 */ /* relate to BTA_GATT_PERM_WRITE_ENCRYPTED in bta_gatt_api.h */
|
||||
#define ESP_GATT_PERM_WRITE_ENC_MITM (1 << 6) /* bit 6 - 0x0040 */ /* relate to BTA_GATT_PERM_WRITE_ENC_MITM in bta_gatt_api.h */
|
||||
#define ESP_GATT_PERM_WRITE_SIGNED (1 << 7) /* bit 7 - 0x0080 */ /* relate to BTA_GATT_PERM_WRITE_SIGNED in bta_gatt_api.h */
|
||||
#define ESP_GATT_PERM_WRITE_SIGNED_MITM (1 << 8) /* bit 8 - 0x0100 */ /* relate to BTA_GATT_PERM_WRITE_SIGNED_MITM in bta_gatt_api.h */
|
||||
typedef uint16_t esp_gatt_perm_t;
|
||||
|
||||
/* relate to BTA_GATT_CHAR_PROP_BIT_xxx in bta_gatt_api.h */
|
||||
/* definition of characteristic properties */
|
||||
#define ESP_GATT_CHAR_PROP_BIT_BROADCAST (1 << 0) /* 0x01 */ /* relate to BTA_GATT_CHAR_PROP_BIT_BROADCAST in bta_gatt_api.h */
|
||||
#define ESP_GATT_CHAR_PROP_BIT_READ (1 << 1) /* 0x02 */ /* relate to BTA_GATT_CHAR_PROP_BIT_READ in bta_gatt_api.h */
|
||||
#define ESP_GATT_CHAR_PROP_BIT_WRITE_NR (1 << 2) /* 0x04 */ /* relate to BTA_GATT_CHAR_PROP_BIT_WRITE_NR in bta_gatt_api.h */
|
||||
#define ESP_GATT_CHAR_PROP_BIT_WRITE (1 << 3) /* 0x08 */ /* relate to BTA_GATT_CHAR_PROP_BIT_WRITE in bta_gatt_api.h */
|
||||
#define ESP_GATT_CHAR_PROP_BIT_NOTIFY (1 << 4) /* 0x10 */ /* relate to BTA_GATT_CHAR_PROP_BIT_NOTIFY in bta_gatt_api.h */
|
||||
#define ESP_GATT_CHAR_PROP_BIT_INDICATE (1 << 5) /* 0x20 */ /* relate to BTA_GATT_CHAR_PROP_BIT_INDICATE in bta_gatt_api.h */
|
||||
#define ESP_GATT_CHAR_PROP_BIT_AUTH (1 << 6) /* 0x40 */ /* relate to BTA_GATT_CHAR_PROP_BIT_AUTH in bta_gatt_api.h */
|
||||
#define ESP_GATT_CHAR_PROP_BIT_EXT_PROP (1 << 7) /* 0x80 */ /* relate to BTA_GATT_CHAR_PROP_BIT_EXT_PROP in bta_gatt_api.h */
|
||||
typedef uint8_t 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 response flag
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
#define ESP_GATT_RSP_BY_APP 0
|
||||
#define ESP_GATT_AUTO_RSP 1
|
||||
/**
|
||||
* @brief if auto_rsp set to ESP_GATT_RSP_BY_APP, means the response of Write/Read operation will by replied by application.
|
||||
if auto_rsp set to ESP_GATT_AUTO_RSP, means the response of Write/Read operation will be replied by GATT stack automatically.
|
||||
*/
|
||||
uint8_t auto_rsp;
|
||||
} esp_attr_control_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief attribute type added to the gatt server database
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
esp_attr_control_t attr_control; /*!< The attribute control type*/
|
||||
esp_attr_desc_t att_desc; /*!< The attribute 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__ */
|
||||
678
components/bt/bluedroid/api/include/esp_gattc_api.h
Normal file
678
components/bt/bluedroid/api/include/esp_gattc_api.h
Normal file
@@ -0,0 +1,678 @@
|
||||
// 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 virtual 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 virtual 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_CONNECT_EVT = 40, /*!< When the ble physical connection is set up, the event comes */
|
||||
ESP_GATTC_DISCONNECT_EVT = 41, /*!< When the ble physical connection disconnected, 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, there is two value for this type:
|
||||
ESP_GATTC_READ_VALUE_TYPE_VALUE(0x0000) and
|
||||
ESP_GATTC_READ_VALUE_TYPE_AGG_FORMAT(0x2905).
|
||||
If the value is ESP_GATTC_READ_VALUE_TYPE_VALUE means it is a generally
|
||||
value type, and if is the type of ESP_GATTC_READ_VALUE_TYPE_AGG_FORMAT,
|
||||
the unit of the value will indicate in the Characteristic
|
||||
aggregate format descriptor */
|
||||
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 */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_CONNECT_EVT
|
||||
*/
|
||||
struct gattc_connect_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 */
|
||||
} connect; /*!< Gatt client callback param of ESP_GATTC_CONNECT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_DISCONNECT_EVT
|
||||
*/
|
||||
struct gattc_disconnect_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 */
|
||||
} disconnect; /*!< Gatt client callback param of ESP_GATTC_DISCONNECT_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 virtual connection to a GATT server. gattc maybe have multiple virtual GATT server connections when multiple app_id registed,
|
||||
* this API only close one virtual GATT server connection. if there exist other virtual GATT server connections,
|
||||
* it does not disconnect the physical connection.
|
||||
* if you want to disconnect the physical connection directly, you can use esp_ble_gap_disconnect(esp_bd_addr_t remote_device).
|
||||
*
|
||||
* @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 prepare write a 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 : GATT characteristic ID of the service.
|
||||
* @param[in] descr_id : characteristic descriptor ID to write.
|
||||
* @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_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 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_err_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_err_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);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Refresh the server cache store in the gattc stack of the remote device
|
||||
*
|
||||
* @param[in] remote_bda: remote device BD address.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gattc_cache_refresh(esp_bd_addr_t remote_bda);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_GATTC_API_H__ */
|
||||
555
components/bt/bluedroid/api/include/esp_gatts_api.h
Normal file
555
components/bt/bluedroid/api/include/esp_gatts_api.h
Normal file
@@ -0,0 +1,555 @@
|
||||
// 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
|
||||
*/
|
||||
struct gatts_open_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
} open; /*!< Gatt server callback param of ESP_GATTS_OPEN_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_CANCEL_OPEN_EVT
|
||||
*/
|
||||
struct gatts_cancel_open_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
} cancel_open; /*!< Gatt server callback param of ESP_GATTS_CANCEL_OPEN_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_CLOSE_EVT
|
||||
*/
|
||||
struct gatts_close_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
} close; /*!< Gatt server callback param of 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_GATT_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_gatt_status_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__ */
|
||||
316
components/bt/bluedroid/bta/ar/bta_ar.c
Normal file
316
components/bt/bluedroid/bta/ar/bta_ar.c
Normal file
@@ -0,0 +1,316 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2008-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 for the audio/video registration module.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
#include <string.h>
|
||||
#include "bta_ar_api.h"
|
||||
#include "bta_ar_int.h"
|
||||
|
||||
#if BTA_AR_INCLUDED
|
||||
|
||||
/* AV control block */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
tBTA_AR_CB bta_ar_cb;
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_ar_id
|
||||
**
|
||||
** Description This function maps sys_id to ar id mask.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static UINT8 bta_ar_id(tBTA_SYS_ID sys_id)
|
||||
{
|
||||
UINT8 mask = 0;
|
||||
if (sys_id == BTA_ID_AV) {
|
||||
mask = BTA_AR_AV_MASK;
|
||||
} else if (sys_id == BTA_ID_AVK) {
|
||||
mask = BTA_AR_AVK_MASK;
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_ar_init
|
||||
**
|
||||
** Description This function is called to register to AVDTP.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_ar_init(void)
|
||||
{
|
||||
/* initialize control block */
|
||||
memset(&bta_ar_cb, 0, sizeof(tBTA_AR_CB));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_ar_reg_avdt
|
||||
**
|
||||
** Description This function is called to register to AVDTP.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_ar_avdt_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data)
|
||||
{
|
||||
/* route the AVDT registration callback to av or avk */
|
||||
if (bta_ar_cb.p_av_conn_cback) {
|
||||
(*bta_ar_cb.p_av_conn_cback)(handle, bd_addr, event, p_data);
|
||||
}
|
||||
if (bta_ar_cb.p_avk_conn_cback) {
|
||||
(*bta_ar_cb.p_avk_conn_cback)(handle, bd_addr, event, p_data);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_ar_reg_avdt
|
||||
**
|
||||
** Description AR module registration to AVDT.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_ar_reg_avdt(tAVDT_REG *p_reg, tAVDT_CTRL_CBACK *p_cback, tBTA_SYS_ID sys_id)
|
||||
{
|
||||
UINT8 mask = 0;
|
||||
|
||||
if (sys_id == BTA_ID_AV) {
|
||||
bta_ar_cb.p_av_conn_cback = p_cback;
|
||||
mask = BTA_AR_AV_MASK;
|
||||
} else if (sys_id == BTA_ID_AVK) {
|
||||
bta_ar_cb.p_avk_conn_cback = p_cback;
|
||||
mask = BTA_AR_AVK_MASK;
|
||||
}
|
||||
#if (BTA_AR_DEBUG == TRUE)
|
||||
else {
|
||||
APPL_TRACE_ERROR("bta_ar_reg_avdt: the registration is from wrong sys_id:%d", sys_id);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mask) {
|
||||
if (bta_ar_cb.avdt_registered == 0) {
|
||||
AVDT_Register(p_reg, bta_ar_avdt_cback);
|
||||
}
|
||||
bta_ar_cb.avdt_registered |= mask;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_ar_dereg_avdt
|
||||
**
|
||||
** Description This function is called to de-register from AVDTP.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_ar_dereg_avdt(tBTA_SYS_ID sys_id)
|
||||
{
|
||||
UINT8 mask = 0;
|
||||
|
||||
if (sys_id == BTA_ID_AV) {
|
||||
bta_ar_cb.p_av_conn_cback = NULL;
|
||||
mask = BTA_AR_AV_MASK;
|
||||
} else if (sys_id == BTA_ID_AVK) {
|
||||
bta_ar_cb.p_avk_conn_cback = NULL;
|
||||
mask = BTA_AR_AVK_MASK;
|
||||
}
|
||||
bta_ar_cb.avdt_registered &= ~mask;
|
||||
|
||||
if (bta_ar_cb.avdt_registered == 0) {
|
||||
AVDT_Deregister();
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_ar_avdt_conn
|
||||
**
|
||||
** Description This function is called to let ar know that some AVDTP profile
|
||||
** is connected for this sys_id.
|
||||
** If the other sys modules started a timer for PENDING_EVT,
|
||||
** the timer can be stopped now.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_ar_avdt_conn(tBTA_SYS_ID sys_id, BD_ADDR bd_addr)
|
||||
{
|
||||
UINT8 event = BTA_AR_AVDT_CONN_EVT;
|
||||
tAVDT_CTRL data;
|
||||
|
||||
if (sys_id == BTA_ID_AV) {
|
||||
if (bta_ar_cb.p_avk_conn_cback) {
|
||||
(*bta_ar_cb.p_avk_conn_cback)(0, bd_addr, event, &data);
|
||||
}
|
||||
} else if (sys_id == BTA_ID_AVK) {
|
||||
if (bta_ar_cb.p_av_conn_cback) {
|
||||
(*bta_ar_cb.p_av_conn_cback)(0, bd_addr, event, &data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_ar_reg_avct
|
||||
**
|
||||
** Description This function is called to register to AVCTP.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_ar_reg_avct(UINT16 mtu, UINT16 mtu_br, UINT8 sec_mask, tBTA_SYS_ID sys_id)
|
||||
{
|
||||
UINT8 mask = bta_ar_id (sys_id);
|
||||
|
||||
if (mask) {
|
||||
if (bta_ar_cb.avct_registered == 0) {
|
||||
AVCT_Register(mtu, mtu_br, sec_mask);
|
||||
}
|
||||
bta_ar_cb.avct_registered |= mask;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_ar_dereg_avct
|
||||
**
|
||||
** Description This function is called to deregister from AVCTP.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_ar_dereg_avct(tBTA_SYS_ID sys_id)
|
||||
{
|
||||
UINT8 mask = bta_ar_id (sys_id);
|
||||
|
||||
bta_ar_cb.avct_registered &= ~mask;
|
||||
|
||||
if (bta_ar_cb.avct_registered == 0) {
|
||||
AVCT_Deregister();
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
**
|
||||
** Function bta_ar_reg_avrc
|
||||
**
|
||||
** Description This function is called to register an SDP record for AVRCP.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
******************************************************************************/
|
||||
void bta_ar_reg_avrc(UINT16 service_uuid, char *service_name, char *provider_name,
|
||||
UINT16 categories, tBTA_SYS_ID sys_id)
|
||||
{
|
||||
UINT8 mask = bta_ar_id (sys_id);
|
||||
UINT8 temp[8], *p;
|
||||
|
||||
if (!mask || !categories) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) {
|
||||
if (bta_ar_cb.sdp_tg_handle == 0) {
|
||||
bta_ar_cb.tg_registered = mask;
|
||||
bta_ar_cb.sdp_tg_handle = SDP_CreateRecord();
|
||||
AVRC_AddRecord(service_uuid, service_name, provider_name, categories, bta_ar_cb.sdp_tg_handle);
|
||||
bta_sys_add_uuid(service_uuid);
|
||||
}
|
||||
/* only one TG is allowed (first-come, first-served).
|
||||
* If sdp_tg_handle is non-0, ignore this request */
|
||||
} else if ((service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) || (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_CONTROL)) {
|
||||
bta_ar_cb.ct_categories [mask - 1] = categories;
|
||||
categories = bta_ar_cb.ct_categories[0] | bta_ar_cb.ct_categories[1];
|
||||
if (bta_ar_cb.sdp_ct_handle == 0) {
|
||||
bta_ar_cb.sdp_ct_handle = SDP_CreateRecord();
|
||||
AVRC_AddRecord(service_uuid, service_name, provider_name, categories, bta_ar_cb.sdp_ct_handle);
|
||||
bta_sys_add_uuid(service_uuid);
|
||||
} else {
|
||||
/* multiple CTs are allowed.
|
||||
* Change supported categories on the second one */
|
||||
p = temp;
|
||||
UINT16_TO_BE_STREAM(p, categories);
|
||||
SDP_AddAttribute(bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE,
|
||||
(UINT32)2, (UINT8 *)temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
**
|
||||
** Function bta_ar_dereg_avrc
|
||||
**
|
||||
** Description This function is called to de-register/delete an SDP record for AVRCP.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
******************************************************************************/
|
||||
void bta_ar_dereg_avrc(UINT16 service_uuid, tBTA_SYS_ID sys_id)
|
||||
{
|
||||
UINT8 mask = bta_ar_id (sys_id);
|
||||
UINT16 categories = 0;
|
||||
UINT8 temp[8], *p;
|
||||
|
||||
if (!mask) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) {
|
||||
if (bta_ar_cb.sdp_tg_handle && mask == bta_ar_cb.tg_registered) {
|
||||
bta_ar_cb.tg_registered = 0;
|
||||
SDP_DeleteRecord(bta_ar_cb.sdp_tg_handle);
|
||||
bta_ar_cb.sdp_tg_handle = 0;
|
||||
bta_sys_remove_uuid(service_uuid);
|
||||
}
|
||||
} else if (service_uuid == UUID_SERVCLASS_AV_REMOTE_CONTROL) {
|
||||
if (bta_ar_cb.sdp_ct_handle) {
|
||||
bta_ar_cb.ct_categories [mask - 1] = 0;
|
||||
categories = bta_ar_cb.ct_categories[0] | bta_ar_cb.ct_categories[1];
|
||||
if (!categories) {
|
||||
/* no CT is still registered - cleaup */
|
||||
SDP_DeleteRecord(bta_ar_cb.sdp_ct_handle);
|
||||
bta_ar_cb.sdp_ct_handle = 0;
|
||||
bta_sys_remove_uuid(service_uuid);
|
||||
} else {
|
||||
/* change supported categories to the remaning one */
|
||||
p = temp;
|
||||
UINT16_TO_BE_STREAM(p, categories);
|
||||
SDP_AddAttribute(bta_ar_cb.sdp_ct_handle, ATTR_ID_SUPPORTED_FEATURES, UINT_DESC_TYPE,
|
||||
(UINT32)2, (UINT8 *)temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* #if BTA_AR_INCLUDED */
|
||||
66
components/bt/bluedroid/bta/ar/bta_ar_int.h
Normal file
66
components/bt/bluedroid/bta/ar/bta_ar_int.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2008-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 audio/video registration
|
||||
* module.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_AR_INT_H
|
||||
#define BTA_AR_INT_H
|
||||
|
||||
#include "bta_av_api.h"
|
||||
|
||||
#if (BTA_AR_INCLUDED == TRUE)
|
||||
|
||||
#ifndef BTA_AR_DEBUG
|
||||
#define BTA_AR_DEBUG FALSE
|
||||
#endif
|
||||
|
||||
#define BTA_AR_AV_MASK 0x01
|
||||
#define BTA_AR_AVK_MASK 0x02
|
||||
|
||||
/* data associated with BTA_AR */
|
||||
typedef struct {
|
||||
tAVDT_CTRL_CBACK *p_av_conn_cback; /* av connection callback function */
|
||||
tAVDT_CTRL_CBACK *p_avk_conn_cback; /* avk connection callback function */
|
||||
UINT8 avdt_registered;
|
||||
UINT8 avct_registered;
|
||||
UINT32 sdp_tg_handle;
|
||||
UINT32 sdp_ct_handle;
|
||||
UINT16 ct_categories[2];
|
||||
UINT8 tg_registered;
|
||||
tBTA_AV_HNDL hndl; /* Handle associated with the stream that rejected the connection. */
|
||||
} tBTA_AR_CB;
|
||||
|
||||
/*****************************************************************************
|
||||
** Global data
|
||||
*****************************************************************************/
|
||||
|
||||
/* control block declaration */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
extern tBTA_AR_CB bta_ar_cb;
|
||||
#else
|
||||
extern tBTA_AR_CB *bta_ar_cb_ptr;
|
||||
#define bta_ar_cb (*bta_ar_cb_ptr)
|
||||
#endif
|
||||
|
||||
#endif ///BTA_AR_INCLUDED == TRUE
|
||||
|
||||
#endif /* BTA_AR_INT_H */
|
||||
2919
components/bt/bluedroid/bta/av/bta_av_aact.c
Normal file
2919
components/bt/bluedroid/bta/av/bta_av_aact.c
Normal file
File diff suppressed because it is too large
Load Diff
1868
components/bt/bluedroid/bta/av/bta_av_act.c
Normal file
1868
components/bt/bluedroid/bta/av/bta_av_act.c
Normal file
File diff suppressed because it is too large
Load Diff
573
components/bt/bluedroid/bta/av/bta_av_api.c
Normal file
573
components/bt/bluedroid/bta/av/bta_av_api.c
Normal file
@@ -0,0 +1,573 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2011-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 the advanced audio/video (AV)
|
||||
* subsystem of BTA, Broadcom's Bluetooth application layer for mobile
|
||||
* phones.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
#if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE)
|
||||
|
||||
#include "bta_api.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_av_api.h"
|
||||
#include "bta_av_int.h"
|
||||
#include "gki.h"
|
||||
#include <string.h>
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
|
||||
static const tBTA_SYS_REG bta_av_reg = {
|
||||
bta_av_hdl_event,
|
||||
BTA_AvDisable
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvEnable
|
||||
**
|
||||
** Description Enable the advanced audio/video service. When the enable
|
||||
** operation is complete the callback function will be
|
||||
** called with a BTA_AV_ENABLE_EVT. This function must
|
||||
** be called before other function in the AV API are
|
||||
** called.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvEnable(tBTA_SEC sec_mask, tBTA_AV_FEAT features, tBTA_AV_CBACK *p_cback)
|
||||
{
|
||||
tBTA_AV_API_ENABLE *p_buf;
|
||||
|
||||
/* register with BTA system manager */
|
||||
bta_sys_register(BTA_ID_AV, &bta_av_reg);
|
||||
|
||||
if ((p_buf = (tBTA_AV_API_ENABLE *) GKI_getbuf(sizeof(tBTA_AV_API_ENABLE))) != NULL) {
|
||||
p_buf->hdr.event = BTA_AV_API_ENABLE_EVT;
|
||||
p_buf->p_cback = p_cback;
|
||||
p_buf->features = features;
|
||||
p_buf->sec_mask = sec_mask;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvDisable
|
||||
**
|
||||
** Description Disable the advanced audio/video service.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvDisable(void)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
bta_sys_deregister(BTA_ID_AV);
|
||||
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_AV_API_DISABLE_EVT;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvRegister
|
||||
**
|
||||
** Description Register the audio or video service to stack. When the
|
||||
** operation is complete the callback function will be
|
||||
** called with a BTA_AV_REGISTER_EVT. This function must
|
||||
** be called before AVDT stream is open.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name, UINT8 app_id, tBTA_AV_DATA_CBACK *p_data_cback, tBTA_AV_CO_FUNCTS *bta_av_cos)
|
||||
{
|
||||
tBTA_AV_API_REG *p_buf;
|
||||
|
||||
|
||||
if ((p_buf = (tBTA_AV_API_REG *) GKI_getbuf(sizeof(tBTA_AV_API_REG))) != NULL) {
|
||||
p_buf->hdr.layer_specific = chnl;
|
||||
p_buf->hdr.event = BTA_AV_API_REGISTER_EVT;
|
||||
if (p_service_name) {
|
||||
BCM_STRNCPY_S(p_buf->p_service_name, sizeof(p_buf->p_service_name), p_service_name, BTA_SERVICE_NAME_LEN);
|
||||
p_buf->p_service_name[BTA_SERVICE_NAME_LEN - 1] = 0;
|
||||
} else {
|
||||
p_buf->p_service_name[0] = 0;
|
||||
}
|
||||
p_buf->app_id = app_id;
|
||||
p_buf->p_app_data_cback = p_data_cback;
|
||||
p_buf->bta_av_cos = bta_av_cos;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvDeregister
|
||||
**
|
||||
** Description Deregister the audio or video service
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvDeregister(tBTA_AV_HNDL hndl)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->layer_specific = hndl;
|
||||
p_buf->event = BTA_AV_API_DEREGISTER_EVT;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvOpen
|
||||
**
|
||||
** Description Opens an advanced audio/video connection to a peer device.
|
||||
** When connection is open callback function is called
|
||||
** with a BTA_AV_OPEN_EVT.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvOpen(BD_ADDR bd_addr, tBTA_AV_HNDL handle, BOOLEAN use_rc, tBTA_SEC sec_mask,
|
||||
UINT16 uuid)
|
||||
{
|
||||
tBTA_AV_API_OPEN *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_AV_API_OPEN *) GKI_getbuf(sizeof(tBTA_AV_API_OPEN))) != NULL) {
|
||||
p_buf->hdr.event = BTA_AV_API_OPEN_EVT;
|
||||
p_buf->hdr.layer_specific = handle;
|
||||
bdcpy(p_buf->bd_addr, bd_addr);
|
||||
p_buf->use_rc = use_rc;
|
||||
p_buf->sec_mask = sec_mask;
|
||||
p_buf->switch_res = BTA_AV_RS_NONE;
|
||||
p_buf->uuid = uuid;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvClose
|
||||
**
|
||||
** Description Close the current streams.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvClose(tBTA_AV_HNDL handle)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_AV_API_CLOSE_EVT;
|
||||
p_buf->layer_specific = handle;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvDisconnect
|
||||
**
|
||||
** Description Close the connection to the address.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvDisconnect(BD_ADDR bd_addr)
|
||||
{
|
||||
tBTA_AV_API_DISCNT *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_AV_API_DISCNT *) GKI_getbuf(sizeof(tBTA_AV_API_DISCNT))) != NULL) {
|
||||
p_buf->hdr.event = BTA_AV_API_DISCONNECT_EVT;
|
||||
bdcpy(p_buf->bd_addr, bd_addr);
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvStart
|
||||
**
|
||||
** Description Start audio/video stream data transfer.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvStart(void)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_AV_API_START_EVT;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvEnable_Sink
|
||||
**
|
||||
** Description Enable/Disable A2DP Sink..
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvEnable_Sink(int enable)
|
||||
{
|
||||
#if (BTA_AV_SINK_INCLUDED == TRUE)
|
||||
BT_HDR *p_buf;
|
||||
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_AV_API_SINK_ENABLE_EVT;
|
||||
p_buf->layer_specific = enable;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvStop
|
||||
**
|
||||
** Description Stop audio/video stream data transfer.
|
||||
** If suspend is TRUE, this function sends AVDT suspend signal
|
||||
** to the connected peer(s).
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvStop(BOOLEAN suspend)
|
||||
{
|
||||
tBTA_AV_API_STOP *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_AV_API_STOP *) GKI_getbuf(sizeof(tBTA_AV_API_STOP))) != NULL) {
|
||||
p_buf->hdr.event = BTA_AV_API_STOP_EVT;
|
||||
p_buf->flush = TRUE;
|
||||
p_buf->suspend = suspend;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvReconfig
|
||||
**
|
||||
** Description Reconfigure the audio/video stream.
|
||||
** If suspend is TRUE, this function tries the suspend/reconfigure
|
||||
** procedure first.
|
||||
** If suspend is FALSE or when suspend/reconfigure fails,
|
||||
** this function closes and re-opens the AVDT connection.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvReconfig(tBTA_AV_HNDL hndl, BOOLEAN suspend, UINT8 sep_info_idx,
|
||||
UINT8 *p_codec_info, UINT8 num_protect, UINT8 *p_protect_info)
|
||||
{
|
||||
tBTA_AV_API_RCFG *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_AV_API_RCFG *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_RCFG) + num_protect))) != NULL) {
|
||||
p_buf->hdr.layer_specific = hndl;
|
||||
p_buf->hdr.event = BTA_AV_API_RECONFIG_EVT;
|
||||
p_buf->num_protect = num_protect;
|
||||
p_buf->suspend = suspend;
|
||||
p_buf->sep_info_idx = sep_info_idx;
|
||||
p_buf->p_protect_info = (UINT8 *)(p_buf + 1);
|
||||
memcpy(p_buf->codec_info, p_codec_info, AVDT_CODEC_SIZE);
|
||||
memcpy(p_buf->p_protect_info, p_protect_info, num_protect);
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvProtectReq
|
||||
**
|
||||
** Description Send a content protection request. This function can only
|
||||
** be used if AV is enabled with feature BTA_AV_FEAT_PROTECT.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvProtectReq(tBTA_AV_HNDL hndl, UINT8 *p_data, UINT16 len)
|
||||
{
|
||||
tBTA_AV_API_PROTECT_REQ *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_AV_API_PROTECT_REQ *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_PROTECT_REQ) + len))) != NULL) {
|
||||
p_buf->hdr.layer_specific = hndl;
|
||||
p_buf->hdr.event = BTA_AV_API_PROTECT_REQ_EVT;
|
||||
p_buf->len = len;
|
||||
if (p_data == NULL) {
|
||||
p_buf->p_data = NULL;
|
||||
} else {
|
||||
p_buf->p_data = (UINT8 *) (p_buf + 1);
|
||||
memcpy(p_buf->p_data, p_data, len);
|
||||
}
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvProtectRsp
|
||||
**
|
||||
** Description Send a content protection response. This function must
|
||||
** be called if a BTA_AV_PROTECT_REQ_EVT is received.
|
||||
** This function can only be used if AV is enabled with
|
||||
** feature BTA_AV_FEAT_PROTECT.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvProtectRsp(tBTA_AV_HNDL hndl, UINT8 error_code, UINT8 *p_data, UINT16 len)
|
||||
{
|
||||
tBTA_AV_API_PROTECT_RSP *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_AV_API_PROTECT_RSP *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_PROTECT_RSP) + len))) != NULL) {
|
||||
p_buf->hdr.layer_specific = hndl;
|
||||
p_buf->hdr.event = BTA_AV_API_PROTECT_RSP_EVT;
|
||||
p_buf->len = len;
|
||||
p_buf->error_code = error_code;
|
||||
if (p_data == NULL) {
|
||||
p_buf->p_data = NULL;
|
||||
} else {
|
||||
p_buf->p_data = (UINT8 *) (p_buf + 1);
|
||||
memcpy(p_buf->p_data, p_data, len);
|
||||
}
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvRemoteCmd
|
||||
**
|
||||
** Description Send a remote control command. This function can only
|
||||
** be used if AV is enabled with feature BTA_AV_FEAT_RCCT.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvRemoteCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_RC rc_id, tBTA_AV_STATE key_state)
|
||||
{
|
||||
tBTA_AV_API_REMOTE_CMD *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_AV_API_REMOTE_CMD *) GKI_getbuf(sizeof(tBTA_AV_API_REMOTE_CMD))) != NULL) {
|
||||
p_buf->hdr.event = BTA_AV_API_REMOTE_CMD_EVT;
|
||||
p_buf->hdr.layer_specific = rc_handle;
|
||||
p_buf->msg.op_id = rc_id;
|
||||
p_buf->msg.state = key_state;
|
||||
p_buf->msg.p_pass_data = NULL;
|
||||
p_buf->msg.pass_len = 0;
|
||||
p_buf->label = label;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvVendorCmd
|
||||
**
|
||||
** Description Send a vendor dependent remote control command. This
|
||||
** function can only be used if AV is enabled with feature
|
||||
** BTA_AV_FEAT_VENDOR.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvVendorCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE cmd_code, UINT8 *p_data, UINT16 len)
|
||||
{
|
||||
tBTA_AV_API_VENDOR *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_AV_API_VENDOR *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_VENDOR) + len))) != NULL) {
|
||||
p_buf->hdr.event = BTA_AV_API_VENDOR_CMD_EVT;
|
||||
p_buf->hdr.layer_specific = rc_handle;
|
||||
p_buf->msg.hdr.ctype = cmd_code;
|
||||
p_buf->msg.hdr.subunit_type = AVRC_SUB_PANEL;
|
||||
p_buf->msg.hdr.subunit_id = 0;
|
||||
p_buf->msg.company_id = p_bta_av_cfg->company_id;
|
||||
p_buf->label = label;
|
||||
p_buf->msg.vendor_len = len;
|
||||
if (p_data == NULL) {
|
||||
p_buf->msg.p_vendor_data = NULL;
|
||||
} else {
|
||||
p_buf->msg.p_vendor_data = (UINT8 *) (p_buf + 1);
|
||||
memcpy(p_buf->msg.p_vendor_data, p_data, len);
|
||||
}
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvVendorRsp
|
||||
**
|
||||
** Description Send a vendor dependent remote control response.
|
||||
** This function must be called if a BTA_AV_VENDOR_CMD_EVT
|
||||
** is received. This function can only be used if AV is
|
||||
** enabled with feature BTA_AV_FEAT_VENDOR.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvVendorRsp(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE rsp_code, UINT8 *p_data, UINT16 len, UINT32 company_id)
|
||||
{
|
||||
tBTA_AV_API_VENDOR *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_AV_API_VENDOR *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_VENDOR) + len))) != NULL) {
|
||||
p_buf->hdr.event = BTA_AV_API_VENDOR_RSP_EVT;
|
||||
p_buf->hdr.layer_specific = rc_handle;
|
||||
p_buf->msg.hdr.ctype = rsp_code;
|
||||
p_buf->msg.hdr.subunit_type = AVRC_SUB_PANEL;
|
||||
p_buf->msg.hdr.subunit_id = 0;
|
||||
if (company_id) {
|
||||
p_buf->msg.company_id = company_id;
|
||||
} else {
|
||||
p_buf->msg.company_id = p_bta_av_cfg->company_id;
|
||||
}
|
||||
p_buf->label = label;
|
||||
p_buf->msg.vendor_len = len;
|
||||
if (p_data == NULL) {
|
||||
p_buf->msg.p_vendor_data = NULL;
|
||||
} else {
|
||||
p_buf->msg.p_vendor_data = (UINT8 *) (p_buf + 1);
|
||||
memcpy(p_buf->msg.p_vendor_data, p_data, len);
|
||||
}
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvOpenRc
|
||||
**
|
||||
** Description Open an AVRCP connection toward the device with the
|
||||
** specified handle
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvOpenRc(tBTA_AV_HNDL handle)
|
||||
{
|
||||
tBTA_AV_API_OPEN_RC *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_AV_API_OPEN_RC *) GKI_getbuf(sizeof(tBTA_AV_API_OPEN_RC))) != NULL) {
|
||||
p_buf->hdr.event = BTA_AV_API_RC_OPEN_EVT;
|
||||
p_buf->hdr.layer_specific = handle;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvCloseRc
|
||||
**
|
||||
** Description Close an AVRCP connection
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvCloseRc(UINT8 rc_handle)
|
||||
{
|
||||
tBTA_AV_API_CLOSE_RC *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_AV_API_CLOSE_RC *) GKI_getbuf(sizeof(tBTA_AV_API_CLOSE_RC))) != NULL) {
|
||||
p_buf->hdr.event = BTA_AV_API_RC_CLOSE_EVT;
|
||||
p_buf->hdr.layer_specific = rc_handle;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvMetaRsp
|
||||
**
|
||||
** Description Send a Metadata/Advanced Control response. The message contained
|
||||
** in p_pkt can be composed with AVRC utility functions.
|
||||
** This function can only be used if AV is enabled with feature
|
||||
** BTA_AV_FEAT_METADATA.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvMetaRsp(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE rsp_code,
|
||||
BT_HDR *p_pkt)
|
||||
{
|
||||
tBTA_AV_API_META_RSP *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_AV_API_META_RSP *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_META_RSP)))) != NULL) {
|
||||
p_buf->hdr.event = BTA_AV_API_META_RSP_EVT;
|
||||
p_buf->hdr.layer_specific = rc_handle;
|
||||
p_buf->rsp_code = rsp_code;
|
||||
p_buf->p_pkt = p_pkt;
|
||||
p_buf->is_rsp = TRUE;
|
||||
p_buf->label = label;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
} else if (p_pkt) {
|
||||
GKI_freebuf(p_pkt);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_AvMetaCmd
|
||||
**
|
||||
** Description Send a Metadata/Advanced Control command. The message contained
|
||||
** in p_pkt can be composed with AVRC utility functions.
|
||||
** This function can only be used if AV is enabled with feature
|
||||
** BTA_AV_FEAT_METADATA.
|
||||
** This message is sent only when the peer supports the TG role.
|
||||
*8 The only command makes sense right now is the absolute volume command.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_AvMetaCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CMD cmd_code, BT_HDR *p_pkt)
|
||||
{
|
||||
tBTA_AV_API_META_RSP *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_AV_API_META_RSP *) GKI_getbuf((UINT16) (sizeof(tBTA_AV_API_META_RSP)))) != NULL) {
|
||||
p_buf->hdr.event = BTA_AV_API_META_RSP_EVT;
|
||||
p_buf->hdr.layer_specific = rc_handle;
|
||||
p_buf->p_pkt = p_pkt;
|
||||
p_buf->rsp_code = cmd_code;
|
||||
p_buf->is_rsp = FALSE;
|
||||
p_buf->label = label;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* BTA_AV_INCLUDED */
|
||||
208
components/bt/bluedroid/bta/av/bta_av_cfg.c
Normal file
208
components/bt/bluedroid/bta/av/bta_av_cfg.c
Normal file
@@ -0,0 +1,208 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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 advanced
|
||||
* audio/video
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "bt_target.h"
|
||||
#include "gki.h"
|
||||
#include "bta_api.h"
|
||||
#include "bta_av_int.h"
|
||||
|
||||
#if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE)
|
||||
|
||||
#ifndef BTA_AV_RC_PASS_RSP_CODE
|
||||
#define BTA_AV_RC_PASS_RSP_CODE BTA_AV_RSP_NOT_IMPL
|
||||
#endif
|
||||
|
||||
const UINT32 bta_av_meta_caps_co_ids[] = {
|
||||
AVRC_CO_METADATA,
|
||||
AVRC_CO_BROADCOM
|
||||
};
|
||||
|
||||
/* AVRCP cupported categories */
|
||||
#define BTA_AV_RC_SUPF_CT (AVRC_SUPF_CT_CAT2)
|
||||
|
||||
/* Added to modify
|
||||
** 1. flush timeout
|
||||
** 2. Remove Group navigation support in SupportedFeatures
|
||||
** 3. GetCapabilities supported event_ids list
|
||||
** 4. GetCapabilities supported event_ids count
|
||||
*/
|
||||
/* Flushing partial avdtp packets can cause some headsets to disconnect the link
|
||||
if receiving partial a2dp frames */
|
||||
const UINT16 bta_av_audio_flush_to[] = {
|
||||
0, /* 1 stream */
|
||||
0, /* 2 streams */
|
||||
0, /* 3 streams */
|
||||
0, /* 4 streams */
|
||||
0 /* 5 streams */
|
||||
}; /* AVDTP audio transport channel flush timeout */
|
||||
|
||||
/* Note: Android doesnt support AVRC_SUPF_TG_GROUP_NAVI */
|
||||
/* Note: if AVRC_SUPF_TG_GROUP_NAVI is set, bta_av_cfg.avrc_group should be TRUE */
|
||||
#if AVRC_METADATA_INCLUDED == TRUE
|
||||
#define BTA_AV_RC_SUPF_TG (AVRC_SUPF_TG_CAT1) /* TODO: | AVRC_SUPF_TG_APP_SETTINGS) */
|
||||
#else
|
||||
#define BTA_AV_RC_SUPF_TG (AVRC_SUPF_TG_CAT1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If the number of event IDs is changed in this array, BTA_AV_ NUM_RC_EVT_IDS also needs to be changed.
|
||||
*/
|
||||
const UINT8 bta_av_meta_caps_evt_ids[] = {
|
||||
AVRC_EVT_PLAY_STATUS_CHANGE,
|
||||
AVRC_EVT_TRACK_CHANGE,
|
||||
AVRC_EVT_PLAY_POS_CHANGED,
|
||||
/* TODO: Add support for these events
|
||||
AVRC_EVT_APP_SETTING_CHANGE,
|
||||
*/
|
||||
};
|
||||
#ifndef BTA_AV_NUM_RC_EVT_IDS
|
||||
#define BTA_AV_NUM_RC_EVT_IDS (sizeof(bta_av_meta_caps_evt_ids) / sizeof(bta_av_meta_caps_evt_ids[0]))
|
||||
#endif /* BTA_AV_NUM_RC_EVT_IDS */
|
||||
|
||||
/* the MTU for the AVRCP browsing channel */
|
||||
#ifndef BTA_AV_MAX_RC_BR_MTU
|
||||
#define BTA_AV_MAX_RC_BR_MTU 1008
|
||||
#endif
|
||||
|
||||
const tBTA_AV_CFG bta_av_cfg = {
|
||||
AVRC_CO_BROADCOM, /* AVRCP Company ID */
|
||||
#if AVRC_METADATA_INCLUDED == TRUE
|
||||
512, /* AVRCP MTU at L2CAP for control channel */
|
||||
#else
|
||||
48, /* AVRCP MTU at L2CAP for control channel */
|
||||
#endif
|
||||
BTA_AV_MAX_RC_BR_MTU, /* AVRCP MTU at L2CAP for browsing channel */
|
||||
BTA_AV_RC_SUPF_CT, /* AVRCP controller categories */
|
||||
BTA_AV_RC_SUPF_TG, /* AVRCP target categories */
|
||||
672, /* AVDTP signaling channel MTU at L2CAP */
|
||||
BTA_AV_MAX_A2DP_MTU, /* AVDTP audio transport channel MTU at L2CAP */
|
||||
bta_av_audio_flush_to, /* AVDTP audio transport channel flush timeout */
|
||||
6, /* AVDTP audio channel max data queue size */
|
||||
BTA_AV_MAX_VDP_MTU, /* AVDTP video transport channel MTU at L2CAP */
|
||||
600, /* AVDTP video transport channel flush timeout */
|
||||
FALSE, /* TRUE, to accept AVRC 1.3 group nevigation command */
|
||||
2, /* company id count in p_meta_co_ids */
|
||||
BTA_AV_NUM_RC_EVT_IDS, /* event id count in p_meta_evt_ids */
|
||||
BTA_AV_RC_PASS_RSP_CODE,/* the default response code for pass through commands */
|
||||
bta_av_meta_caps_co_ids,/* the metadata Get Capabilities response for company id */
|
||||
bta_av_meta_caps_evt_ids,/* the the metadata Get Capabilities response for event id */
|
||||
NULL, /* the action function table for VDP stream */
|
||||
NULL, /* action function to register VDP */
|
||||
{0}, /* Default AVRCP controller name */
|
||||
{0}, /* Default AVRCP target name */
|
||||
};
|
||||
|
||||
tBTA_AV_CFG *p_bta_av_cfg = (tBTA_AV_CFG *) &bta_av_cfg;
|
||||
|
||||
const UINT16 bta_av_rc_id[] = {
|
||||
0x0000, /* bit mask: 0=SELECT, 1=UP, 2=DOWN, 3=LEFT,
|
||||
4=RIGHT, 5=RIGHT_UP, 6=RIGHT_DOWN, 7=LEFT_UP,
|
||||
8=LEFT_DOWN, 9=ROOT_MENU, 10=SETUP_MENU, 11=CONT_MENU,
|
||||
12=FAV_MENU, 13=EXIT */
|
||||
|
||||
0, /* not used */
|
||||
|
||||
0x0000, /* bit mask: 0=0, 1=1, 2=2, 3=3,
|
||||
4=4, 5=5, 6=6, 7=7,
|
||||
8=8, 9=9, 10=DOT, 11=ENTER,
|
||||
12=CLEAR */
|
||||
|
||||
0x0000, /* bit mask: 0=CHAN_UP, 1=CHAN_DOWN, 2=PREV_CHAN, 3=SOUND_SEL,
|
||||
4=INPUT_SEL, 5=DISP_INFO, 6=HELP, 7=PAGE_UP,
|
||||
8=PAGE_DOWN */
|
||||
|
||||
#if (BTA_AV_RC_PASS_RSP_CODE == BTA_AV_RSP_INTERIM)
|
||||
/* btui_app provides an example of how to leave the decision of rejecting a command or not
|
||||
* based on which media player is currently addressed (this is only applicable for AVRCP 1.4 or later)
|
||||
* If the decision is per player for a particular rc_id, the related bit is clear (not set) */
|
||||
0x0070, /* bit mask: 0=POWER, 1=VOL_UP, 2=VOL_DOWN, 3=MUTE,
|
||||
4=PLAY, 5=STOP, 6=PAUSE, 7=RECORD,
|
||||
8=REWIND, 9=FAST_FOR, 10=EJECT, 11=FORWARD,
|
||||
12=BACKWARD */
|
||||
#else
|
||||
#if (defined BTA_AVRCP_FF_RW_SUPPORT) && (BTA_AVRCP_FF_RW_SUPPORT == TRUE)
|
||||
0x1b70, /* bit mask: 0=POWER, 1=VOL_UP, 2=VOL_DOWN, 3=MUTE,
|
||||
4=PLAY, 5=STOP, 6=PAUSE, 7=RECORD,
|
||||
8=REWIND, 9=FAST_FOR, 10=EJECT, 11=FORWARD,
|
||||
12=BACKWARD */
|
||||
#else
|
||||
0x1870, /* bit mask: 0=POWER, 1=VOL_UP, 2=VOL_DOWN, 3=MUTE,
|
||||
4=PLAY, 5=STOP, 6=PAUSE, 7=RECORD,
|
||||
8=REWIND, 9=FAST_FOR, 10=EJECT, 11=FORWARD,
|
||||
12=BACKWARD */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
0x0000, /* bit mask: 0=ANGLE, 1=SUBPICT */
|
||||
|
||||
0, /* not used */
|
||||
|
||||
0x0000 /* bit mask: 0=not used, 1=F1, 2=F2, 3=F3,
|
||||
4=F4, 5=F5 */
|
||||
};
|
||||
|
||||
#if (BTA_AV_RC_PASS_RSP_CODE == BTA_AV_RSP_INTERIM)
|
||||
const UINT16 bta_av_rc_id_ac[] = {
|
||||
0x0000, /* bit mask: 0=SELECT, 1=UP, 2=DOWN, 3=LEFT,
|
||||
4=RIGHT, 5=RIGHT_UP, 6=RIGHT_DOWN, 7=LEFT_UP,
|
||||
8=LEFT_DOWN, 9=ROOT_MENU, 10=SETUP_MENU, 11=CONT_MENU,
|
||||
12=FAV_MENU, 13=EXIT */
|
||||
|
||||
0, /* not used */
|
||||
|
||||
0x0000, /* bit mask: 0=0, 1=1, 2=2, 3=3,
|
||||
4=4, 5=5, 6=6, 7=7,
|
||||
8=8, 9=9, 10=DOT, 11=ENTER,
|
||||
12=CLEAR */
|
||||
|
||||
0x0000, /* bit mask: 0=CHAN_UP, 1=CHAN_DOWN, 2=PREV_CHAN, 3=SOUND_SEL,
|
||||
4=INPUT_SEL, 5=DISP_INFO, 6=HELP, 7=PAGE_UP,
|
||||
8=PAGE_DOWN */
|
||||
|
||||
/* btui_app provides an example of how to leave the decision of rejecting a command or not
|
||||
* based on which media player is currently addressed (this is only applicable for AVRCP 1.4 or later)
|
||||
* If the decision is per player for a particular rc_id, the related bit is set */
|
||||
0x1800, /* bit mask: 0=POWER, 1=VOL_UP, 2=VOL_DOWN, 3=MUTE,
|
||||
4=PLAY, 5=STOP, 6=PAUSE, 7=RECORD,
|
||||
8=REWIND, 9=FAST_FOR, 10=EJECT, 11=FORWARD,
|
||||
12=BACKWARD */
|
||||
|
||||
0x0000, /* bit mask: 0=ANGLE, 1=SUBPICT */
|
||||
|
||||
0, /* not used */
|
||||
|
||||
0x0000 /* bit mask: 0=not used, 1=F1, 2=F2, 3=F3,
|
||||
4=F4, 5=F5 */
|
||||
};
|
||||
UINT16 *p_bta_av_rc_id_ac = (UINT16 *) bta_av_rc_id_ac;
|
||||
#else
|
||||
UINT16 *p_bta_av_rc_id_ac = NULL;
|
||||
#endif
|
||||
|
||||
UINT16 *p_bta_av_rc_id = (UINT16 *) bta_av_rc_id;
|
||||
|
||||
#endif /* if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE) */
|
||||
97
components/bt/bluedroid/bta/av/bta_av_ci.c
Normal file
97
components/bt/bluedroid/bta/av/bta_av_ci.c
Normal file
@@ -0,0 +1,97 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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 implementation file for advanced audio/video call-in
|
||||
* functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
#include "bta_api.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_av_int.h"
|
||||
#include "bta_av_ci.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE)
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_ci_src_data_ready
|
||||
**
|
||||
** Description This function sends an event to the AV indicating that
|
||||
** the phone has audio stream data ready to send and AV
|
||||
** should call bta_av_co_audio_src_data_path() or
|
||||
** bta_av_co_video_src_data_path().
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_av_ci_src_data_ready(tBTA_AV_CHNL chnl)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->layer_specific = chnl;
|
||||
p_buf->event = BTA_AV_CI_SRC_DATA_READY_EVT;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_ci_setconfig
|
||||
**
|
||||
** Description This function must be called in response to function
|
||||
** bta_av_co_audio_setconfig() or bta_av_co_video_setconfig.
|
||||
** Parameter err_code is set to an AVDTP status value;
|
||||
** AVDT_SUCCESS if the codec configuration is ok,
|
||||
** otherwise error.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_av_ci_setconfig(tBTA_AV_HNDL hndl, UINT8 err_code, UINT8 category,
|
||||
UINT8 num_seid, UINT8 *p_seid, BOOLEAN recfg_needed, UINT8 avdt_handle)
|
||||
{
|
||||
tBTA_AV_CI_SETCONFIG *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_AV_CI_SETCONFIG *) GKI_getbuf(sizeof(tBTA_AV_CI_SETCONFIG))) != NULL) {
|
||||
p_buf->hdr.layer_specific = hndl;
|
||||
p_buf->hdr.event = (err_code == AVDT_SUCCESS) ?
|
||||
BTA_AV_CI_SETCONFIG_OK_EVT : BTA_AV_CI_SETCONFIG_FAIL_EVT;
|
||||
p_buf->err_code = err_code;
|
||||
p_buf->category = category;
|
||||
p_buf->recfg_needed = recfg_needed;
|
||||
p_buf->num_seid = num_seid;
|
||||
p_buf->avdt_handle = avdt_handle;
|
||||
if (p_seid && num_seid) {
|
||||
p_buf->p_seid = (UINT8 *)(p_buf + 1);
|
||||
memcpy(p_buf->p_seid, p_seid, num_seid);
|
||||
} else {
|
||||
p_buf->p_seid = NULL;
|
||||
p_buf->num_seid = 0;
|
||||
}
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* #if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE) */
|
||||
708
components/bt/bluedroid/bta/av/bta_av_int.h
Normal file
708
components/bt/bluedroid/bta/av/bta_av_int.h
Normal file
@@ -0,0 +1,708 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004-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 advanced audio/video.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_AV_INT_H
|
||||
#define BTA_AV_INT_H
|
||||
|
||||
#include "bta_sys.h"
|
||||
#include "bta_api.h"
|
||||
#include "bta_av_api.h"
|
||||
#include "avdt_api.h"
|
||||
#include "bta_av_co.h"
|
||||
#include "list.h"
|
||||
|
||||
#if (BTA_AV_INCLUDED == TRUE)
|
||||
|
||||
#define BTA_AV_DEBUG TRUE
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
|
||||
enum {
|
||||
/* these events are handled by the AV main state machine */
|
||||
BTA_AV_API_DISABLE_EVT = BTA_SYS_EVT_START(BTA_ID_AV),
|
||||
BTA_AV_API_REMOTE_CMD_EVT,
|
||||
BTA_AV_API_VENDOR_CMD_EVT,
|
||||
BTA_AV_API_VENDOR_RSP_EVT,
|
||||
BTA_AV_API_META_RSP_EVT,
|
||||
BTA_AV_API_RC_CLOSE_EVT,
|
||||
BTA_AV_AVRC_OPEN_EVT,
|
||||
BTA_AV_AVRC_MSG_EVT,
|
||||
BTA_AV_AVRC_NONE_EVT,
|
||||
|
||||
/* these events are handled by the AV stream state machine */
|
||||
BTA_AV_API_OPEN_EVT,
|
||||
BTA_AV_API_CLOSE_EVT,
|
||||
BTA_AV_AP_START_EVT, /* the following 2 events must be in the same order as the *API_*EVT */
|
||||
BTA_AV_AP_STOP_EVT,
|
||||
BTA_AV_API_RECONFIG_EVT,
|
||||
BTA_AV_API_PROTECT_REQ_EVT,
|
||||
BTA_AV_API_PROTECT_RSP_EVT,
|
||||
BTA_AV_API_RC_OPEN_EVT,
|
||||
BTA_AV_SRC_DATA_READY_EVT,
|
||||
BTA_AV_CI_SETCONFIG_OK_EVT,
|
||||
BTA_AV_CI_SETCONFIG_FAIL_EVT,
|
||||
BTA_AV_SDP_DISC_OK_EVT,
|
||||
BTA_AV_SDP_DISC_FAIL_EVT,
|
||||
BTA_AV_STR_DISC_OK_EVT,
|
||||
BTA_AV_STR_DISC_FAIL_EVT,
|
||||
BTA_AV_STR_GETCAP_OK_EVT,
|
||||
BTA_AV_STR_GETCAP_FAIL_EVT,
|
||||
BTA_AV_STR_OPEN_OK_EVT,
|
||||
BTA_AV_STR_OPEN_FAIL_EVT,
|
||||
BTA_AV_STR_START_OK_EVT,
|
||||
BTA_AV_STR_START_FAIL_EVT,
|
||||
BTA_AV_STR_CLOSE_EVT,
|
||||
BTA_AV_STR_CONFIG_IND_EVT,
|
||||
BTA_AV_STR_SECURITY_IND_EVT,
|
||||
BTA_AV_STR_SECURITY_CFM_EVT,
|
||||
BTA_AV_STR_WRITE_CFM_EVT,
|
||||
BTA_AV_STR_SUSPEND_CFM_EVT,
|
||||
BTA_AV_STR_RECONFIG_CFM_EVT,
|
||||
BTA_AV_AVRC_TIMER_EVT,
|
||||
BTA_AV_AVDT_CONNECT_EVT,
|
||||
BTA_AV_AVDT_DISCONNECT_EVT,
|
||||
BTA_AV_ROLE_CHANGE_EVT,
|
||||
BTA_AV_AVDT_DELAY_RPT_EVT,
|
||||
BTA_AV_ACP_CONNECT_EVT,
|
||||
|
||||
/* these events are handled outside of the state machine */
|
||||
BTA_AV_API_ENABLE_EVT,
|
||||
BTA_AV_API_REGISTER_EVT,
|
||||
BTA_AV_API_DEREGISTER_EVT,
|
||||
BTA_AV_API_DISCONNECT_EVT,
|
||||
BTA_AV_CI_SRC_DATA_READY_EVT,
|
||||
BTA_AV_SIG_CHG_EVT,
|
||||
BTA_AV_SIG_TIMER_EVT,
|
||||
BTA_AV_SDP_AVRC_DISC_EVT,
|
||||
BTA_AV_AVRC_CLOSE_EVT,
|
||||
BTA_AV_CONN_CHG_EVT,
|
||||
BTA_AV_DEREG_COMP_EVT,
|
||||
#if (BTA_AV_SINK_INCLUDED == TRUE)
|
||||
BTA_AV_API_SINK_ENABLE_EVT,
|
||||
#endif
|
||||
#if (AVDT_REPORTING == TRUE)
|
||||
BTA_AV_AVDT_RPT_CONN_EVT,
|
||||
#endif
|
||||
BTA_AV_API_START_EVT, /* the following 2 events must be in the same order as the *AP_*EVT */
|
||||
BTA_AV_API_STOP_EVT
|
||||
};
|
||||
|
||||
/* events for AV control block state machine */
|
||||
#define BTA_AV_FIRST_SM_EVT BTA_AV_API_DISABLE_EVT
|
||||
#define BTA_AV_LAST_SM_EVT BTA_AV_AVRC_NONE_EVT
|
||||
|
||||
/* events for AV stream control block state machine */
|
||||
#define BTA_AV_FIRST_SSM_EVT BTA_AV_API_OPEN_EVT
|
||||
|
||||
/* events that do not go through state machine */
|
||||
#define BTA_AV_FIRST_NSM_EVT BTA_AV_API_ENABLE_EVT
|
||||
#define BTA_AV_LAST_NSM_EVT BTA_AV_API_STOP_EVT
|
||||
|
||||
/* API events passed to both SSMs (by bta_av_api_to_ssm) */
|
||||
#define BTA_AV_FIRST_A2S_API_EVT BTA_AV_API_START_EVT
|
||||
#define BTA_AV_FIRST_A2S_SSM_EVT BTA_AV_AP_START_EVT
|
||||
|
||||
#define BTA_AV_LAST_EVT BTA_AV_API_STOP_EVT
|
||||
|
||||
/* maximum number of SEPS in stream discovery results */
|
||||
#define BTA_AV_NUM_SEPS 32
|
||||
|
||||
/* initialization value for AVRC handle */
|
||||
#define BTA_AV_RC_HANDLE_NONE 0xFF
|
||||
|
||||
/* size of database for service discovery */
|
||||
#define BTA_AV_DISC_BUF_SIZE 1000
|
||||
|
||||
/* offset of media type in codec info byte array */
|
||||
#define BTA_AV_MEDIA_TYPE_IDX 1
|
||||
|
||||
/* maximum length of AVDTP security data */
|
||||
#define BTA_AV_SECURITY_MAX_LEN 400
|
||||
|
||||
/* check number of buffers queued at L2CAP when this amount of buffers are queued to L2CAP */
|
||||
#define BTA_AV_QUEUE_DATA_CHK_NUM L2CAP_HIGH_PRI_MIN_XMIT_QUOTA
|
||||
|
||||
/* the number of ACL links with AVDT */
|
||||
#define BTA_AV_NUM_LINKS AVDT_NUM_LINKS
|
||||
|
||||
#define BTA_AV_CO_ID_TO_BE_STREAM(p, u32) {*(p)++ = (UINT8)((u32) >> 16); *(p)++ = (UINT8)((u32) >> 8); *(p)++ = (UINT8)(u32); }
|
||||
#define BTA_AV_BE_STREAM_TO_CO_ID(u32, p) {u32 = (((UINT32)(*((p) + 2))) + (((UINT32)(*((p) + 1))) << 8) + (((UINT32)(*(p))) << 16)); (p) += 3;}
|
||||
|
||||
/* these bits are defined for bta_av_cb.multi_av */
|
||||
#define BTA_AV_MULTI_AV_SUPPORTED 0x01
|
||||
#define BTA_AV_MULTI_AV_IN_USE 0x02
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Data types
|
||||
*****************************************************************************/
|
||||
#if 0
|
||||
/* function types for call-out functions */
|
||||
typedef BOOLEAN (*tBTA_AV_CO_INIT) (UINT8 *p_codec_type, UINT8 *p_codec_info,
|
||||
UINT8 *p_num_protect, UINT8 *p_protect_info, UINT8 index);
|
||||
typedef void (*tBTA_AV_CO_DISC_RES) (tBTA_AV_HNDL hndl, UINT8 num_seps,
|
||||
UINT8 num_snk, UINT8 num_src, BD_ADDR addr, UINT16 uuid_local);
|
||||
typedef UINT8 (*tBTA_AV_CO_GETCFG) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
|
||||
UINT8 *p_codec_info, UINT8 *p_sep_info_idx, UINT8 seid,
|
||||
UINT8 *p_num_protect, UINT8 *p_protect_info);
|
||||
typedef void (*tBTA_AV_CO_SETCFG) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type,
|
||||
UINT8 *p_codec_info, UINT8 seid, BD_ADDR addr,
|
||||
UINT8 num_protect, UINT8 *p_protect_info,
|
||||
UINT8 t_local_sep, UINT8 avdt_handle);
|
||||
typedef void (*tBTA_AV_CO_OPEN) (tBTA_AV_HNDL hndl,
|
||||
tBTA_AV_CODEC codec_type, UINT8 *p_codec_info,
|
||||
UINT16 mtu);
|
||||
typedef void (*tBTA_AV_CO_CLOSE) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, UINT16 mtu);
|
||||
typedef void (*tBTA_AV_CO_START) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type, UINT8 *p_codec_info, BOOLEAN *p_no_rtp_hdr);
|
||||
typedef void (*tBTA_AV_CO_STOP) (tBTA_AV_HNDL hndl, tBTA_AV_CODEC codec_type);
|
||||
typedef void *(*tBTA_AV_CO_DATAPATH) (tBTA_AV_CODEC codec_type,
|
||||
UINT32 *p_len, UINT32 *p_timestamp);
|
||||
typedef void (*tBTA_AV_CO_DELAY) (tBTA_AV_HNDL hndl, UINT16 delay);
|
||||
|
||||
/* the call-out functions for one stream */
|
||||
typedef struct {
|
||||
tBTA_AV_CO_INIT init;
|
||||
tBTA_AV_CO_DISC_RES disc_res;
|
||||
tBTA_AV_CO_GETCFG getcfg;
|
||||
tBTA_AV_CO_SETCFG setcfg;
|
||||
tBTA_AV_CO_OPEN open;
|
||||
tBTA_AV_CO_CLOSE close;
|
||||
tBTA_AV_CO_START start;
|
||||
tBTA_AV_CO_STOP stop;
|
||||
tBTA_AV_CO_DATAPATH data;
|
||||
tBTA_AV_CO_DELAY delay;
|
||||
} tBTA_AV_CO_FUNCTS;
|
||||
#endif
|
||||
|
||||
/* data type for BTA_AV_API_ENABLE_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_AV_CBACK *p_cback;
|
||||
tBTA_AV_FEAT features;
|
||||
tBTA_SEC sec_mask;
|
||||
} tBTA_AV_API_ENABLE;
|
||||
|
||||
/* data type for BTA_AV_API_REG_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
char p_service_name[BTA_SERVICE_NAME_LEN + 1];
|
||||
UINT8 app_id;
|
||||
tBTA_AV_DATA_CBACK *p_app_data_cback;
|
||||
tBTA_AV_CO_FUNCTS *bta_av_cos;
|
||||
} tBTA_AV_API_REG;
|
||||
|
||||
|
||||
enum {
|
||||
BTA_AV_RS_NONE, /* straight API call */
|
||||
BTA_AV_RS_OK, /* the role switch result - successful */
|
||||
BTA_AV_RS_FAIL, /* the role switch result - failed */
|
||||
BTA_AV_RS_DONE /* the role switch is done - continue */
|
||||
};
|
||||
typedef UINT8 tBTA_AV_RS_RES;
|
||||
/* data type for BTA_AV_API_OPEN_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR bd_addr;
|
||||
BOOLEAN use_rc;
|
||||
tBTA_SEC sec_mask;
|
||||
tBTA_AV_RS_RES switch_res;
|
||||
UINT16 uuid; /* uuid of initiator */
|
||||
} tBTA_AV_API_OPEN;
|
||||
|
||||
/* data type for BTA_AV_API_STOP_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BOOLEAN suspend;
|
||||
BOOLEAN flush;
|
||||
} tBTA_AV_API_STOP;
|
||||
|
||||
/* data type for BTA_AV_API_DISCONNECT_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR bd_addr;
|
||||
} tBTA_AV_API_DISCNT;
|
||||
|
||||
/* data type for BTA_AV_API_PROTECT_REQ_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT8 *p_data;
|
||||
UINT16 len;
|
||||
} tBTA_AV_API_PROTECT_REQ;
|
||||
|
||||
/* data type for BTA_AV_API_PROTECT_RSP_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT8 *p_data;
|
||||
UINT16 len;
|
||||
UINT8 error_code;
|
||||
} tBTA_AV_API_PROTECT_RSP;
|
||||
|
||||
/* data type for BTA_AV_API_REMOTE_CMD_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tAVRC_MSG_PASS msg;
|
||||
UINT8 label;
|
||||
} tBTA_AV_API_REMOTE_CMD;
|
||||
|
||||
/* data type for BTA_AV_API_VENDOR_CMD_EVT and RSP */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tAVRC_MSG_VENDOR msg;
|
||||
UINT8 label;
|
||||
} tBTA_AV_API_VENDOR;
|
||||
|
||||
/* data type for BTA_AV_API_RC_OPEN_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
} tBTA_AV_API_OPEN_RC;
|
||||
|
||||
/* data type for BTA_AV_API_RC_CLOSE_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
} tBTA_AV_API_CLOSE_RC;
|
||||
|
||||
/* data type for BTA_AV_API_META_RSP_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BOOLEAN is_rsp;
|
||||
UINT8 label;
|
||||
tBTA_AV_CODE rsp_code;
|
||||
BT_HDR *p_pkt;
|
||||
} tBTA_AV_API_META_RSP;
|
||||
|
||||
|
||||
/* data type for BTA_AV_API_RECONFIG_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT8 codec_info[AVDT_CODEC_SIZE]; /* codec configuration */
|
||||
UINT8 *p_protect_info;
|
||||
UINT8 num_protect;
|
||||
BOOLEAN suspend;
|
||||
UINT8 sep_info_idx;
|
||||
} tBTA_AV_API_RCFG;
|
||||
|
||||
/* data type for BTA_AV_CI_SETCONFIG_OK_EVT and BTA_AV_CI_SETCONFIG_FAIL_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_AV_HNDL hndl;
|
||||
UINT8 err_code;
|
||||
UINT8 category;
|
||||
UINT8 num_seid;
|
||||
UINT8 *p_seid;
|
||||
BOOLEAN recfg_needed;
|
||||
UINT8 avdt_handle; /* local sep type for which this stream will be set up */
|
||||
} tBTA_AV_CI_SETCONFIG;
|
||||
|
||||
/* data type for all stream events from AVDTP */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tAVDT_CFG cfg; /* configuration/capabilities parameters */
|
||||
tAVDT_CTRL msg; /* AVDTP callback message parameters */
|
||||
BD_ADDR bd_addr; /* bd address */
|
||||
UINT8 handle;
|
||||
UINT8 avdt_event;
|
||||
BOOLEAN initiator; /* TRUE, if local device initiates the SUSPEND */
|
||||
} tBTA_AV_STR_MSG;
|
||||
|
||||
/* data type for BTA_AV_AVRC_MSG_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tAVRC_MSG msg;
|
||||
UINT8 handle;
|
||||
UINT8 label;
|
||||
UINT8 opcode;
|
||||
} tBTA_AV_RC_MSG;
|
||||
|
||||
/* data type for BTA_AV_AVRC_OPEN_EVT, BTA_AV_AVRC_CLOSE_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR peer_addr;
|
||||
UINT8 handle;
|
||||
} tBTA_AV_RC_CONN_CHG;
|
||||
|
||||
/* data type for BTA_AV_CONN_CHG_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR peer_addr;
|
||||
BOOLEAN is_up;
|
||||
} tBTA_AV_CONN_CHG;
|
||||
|
||||
/* data type for BTA_AV_ROLE_CHANGE_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT8 new_role;
|
||||
UINT8 hci_status;
|
||||
} tBTA_AV_ROLE_RES;
|
||||
|
||||
/* data type for BTA_AV_SDP_DISC_OK_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT16 avdt_version; /* AVDTP protocol version */
|
||||
} tBTA_AV_SDP_RES;
|
||||
|
||||
/* type for SEP control block */
|
||||
typedef struct {
|
||||
UINT8 av_handle; /* AVDTP handle */
|
||||
tBTA_AV_CODEC codec_type; /* codec type */
|
||||
UINT8 tsep; /* SEP type of local SEP */
|
||||
tBTA_AV_DATA_CBACK *p_app_data_cback; /* Application callback for media packets */
|
||||
} tBTA_AV_SEP;
|
||||
|
||||
|
||||
/* initiator/acceptor role for adaption */
|
||||
#define BTA_AV_ROLE_AD_INT 0x00 /* initiator */
|
||||
#define BTA_AV_ROLE_AD_ACP 0x01 /* acceptor */
|
||||
|
||||
/* initiator/acceptor signaling roles */
|
||||
#define BTA_AV_ROLE_START_ACP 0x00
|
||||
#define BTA_AV_ROLE_START_INT 0x10 /* do not change this value */
|
||||
|
||||
#define BTA_AV_ROLE_SUSPEND 0x20 /* suspending on start */
|
||||
#define BTA_AV_ROLE_SUSPEND_OPT 0x40 /* Suspend on Start option is set */
|
||||
|
||||
/* union of all event datatypes */
|
||||
typedef union {
|
||||
BT_HDR hdr;
|
||||
tBTA_AV_API_ENABLE api_enable;
|
||||
tBTA_AV_API_REG api_reg;
|
||||
tBTA_AV_API_OPEN api_open;
|
||||
tBTA_AV_API_STOP api_stop;
|
||||
tBTA_AV_API_DISCNT api_discnt;
|
||||
tBTA_AV_API_PROTECT_REQ api_protect_req;
|
||||
tBTA_AV_API_PROTECT_RSP api_protect_rsp;
|
||||
tBTA_AV_API_REMOTE_CMD api_remote_cmd;
|
||||
tBTA_AV_API_VENDOR api_vendor;
|
||||
tBTA_AV_API_RCFG api_reconfig;
|
||||
tBTA_AV_CI_SETCONFIG ci_setconfig;
|
||||
tBTA_AV_STR_MSG str_msg;
|
||||
tBTA_AV_RC_MSG rc_msg;
|
||||
tBTA_AV_RC_CONN_CHG rc_conn_chg;
|
||||
tBTA_AV_CONN_CHG conn_chg;
|
||||
tBTA_AV_ROLE_RES role_res;
|
||||
tBTA_AV_SDP_RES sdp_res;
|
||||
tBTA_AV_API_META_RSP api_meta_rsp;
|
||||
} tBTA_AV_DATA;
|
||||
|
||||
typedef void (tBTA_AV_VDP_DATA_ACT)(void *p_scb);
|
||||
|
||||
typedef struct {
|
||||
tBTA_AV_VDP_DATA_ACT *p_act;
|
||||
UINT8 *p_frame;
|
||||
UINT16 buf_size;
|
||||
UINT32 len;
|
||||
UINT32 offset;
|
||||
UINT32 timestamp;
|
||||
} tBTA_AV_VF_INFO;
|
||||
|
||||
typedef union {
|
||||
tBTA_AV_VF_INFO vdp; /* used for video channels only */
|
||||
tBTA_AV_API_OPEN open; /* used only before open and role switch
|
||||
is needed on another AV channel */
|
||||
} tBTA_AV_Q_INFO;
|
||||
|
||||
#define BTA_AV_Q_TAG_OPEN 0x01 /* after API_OPEN, before STR_OPENED */
|
||||
#define BTA_AV_Q_TAG_START 0x02 /* before start sending media packets */
|
||||
#define BTA_AV_Q_TAG_STREAM 0x03 /* during streaming */
|
||||
|
||||
#define BTA_AV_WAIT_ACP_CAPS_ON 0x01 /* retriving the peer capabilities */
|
||||
#define BTA_AV_WAIT_ACP_CAPS_STARTED 0x02 /* started while retriving peer capabilities */
|
||||
#define BTA_AV_WAIT_ROLE_SW_RES_OPEN 0x04 /* waiting for role switch result after API_OPEN, before STR_OPENED */
|
||||
#define BTA_AV_WAIT_ROLE_SW_RES_START 0x08 /* waiting for role switch result before streaming */
|
||||
#define BTA_AV_WAIT_ROLE_SW_STARTED 0x10 /* started while waiting for role switch result */
|
||||
#define BTA_AV_WAIT_ROLE_SW_RETRY 0x20 /* set when retry on timeout */
|
||||
#define BTA_AV_WAIT_CHECK_RC 0x40 /* set when the timer is used by role switch */
|
||||
#define BTA_AV_WAIT_ROLE_SW_FAILED 0x80 /* role switch failed */
|
||||
|
||||
#define BTA_AV_WAIT_ROLE_SW_BITS (BTA_AV_WAIT_ROLE_SW_RES_OPEN|BTA_AV_WAIT_ROLE_SW_RES_START|BTA_AV_WAIT_ROLE_SW_STARTED|BTA_AV_WAIT_ROLE_SW_RETRY)
|
||||
|
||||
/* Bitmap for collision, coll_mask */
|
||||
#define BTA_AV_COLL_INC_TMR 0x01 /* Timer is running for incoming L2C connection */
|
||||
#define BTA_AV_COLL_API_CALLED 0x02 /* API open was called while incoming timer is running */
|
||||
|
||||
/* type for AV stream control block */
|
||||
typedef struct {
|
||||
const tBTA_AV_ACT *p_act_tbl; /* the action table for stream state machine */
|
||||
const tBTA_AV_CO_FUNCTS *p_cos; /* the associated callout functions */
|
||||
tSDP_DISCOVERY_DB *p_disc_db; /* pointer to discovery database */
|
||||
tBTA_AV_SEP seps[BTA_AV_MAX_SEPS];
|
||||
tAVDT_CFG *p_cap; /* buffer used for get capabilities */
|
||||
list_t *a2d_list; /* used for audio channels only */
|
||||
tBTA_AV_Q_INFO q_info;
|
||||
tAVDT_SEP_INFO sep_info[BTA_AV_NUM_SEPS]; /* stream discovery results */
|
||||
tAVDT_CFG cfg; /* local SEP configuration */
|
||||
TIMER_LIST_ENT timer; /* delay timer for AVRC CT */
|
||||
BD_ADDR peer_addr; /* peer BD address */
|
||||
UINT16 l2c_cid; /* L2CAP channel ID */
|
||||
UINT16 stream_mtu; /* MTU of stream */
|
||||
UINT16 avdt_version; /* the avdt version of peer device */
|
||||
tBTA_SEC sec_mask; /* security mask */
|
||||
tBTA_AV_CODEC codec_type; /* codec type */
|
||||
UINT8 media_type; /* Media type */
|
||||
BOOLEAN cong; /* TRUE if AVDTP congested */
|
||||
tBTA_AV_STATUS open_status; /* open failure status */
|
||||
tBTA_AV_CHNL chnl; /* the channel: audio/video */
|
||||
tBTA_AV_HNDL hndl; /* the handle: ((hdi + 1)|chnl) */
|
||||
UINT16 cur_psc_mask; /* Protocol service capabilities mask for current connection */
|
||||
UINT8 avdt_handle; /* AVDTP handle */
|
||||
UINT8 hdi; /* the index to SCB[] */
|
||||
UINT8 num_seps; /* number of seps returned by stream discovery */
|
||||
UINT8 num_disc_snks; /* number of discovered snks */
|
||||
UINT8 num_disc_srcs; /* number of discovered srcs */
|
||||
UINT8 sep_info_idx; /* current index into sep_info */
|
||||
UINT8 sep_idx; /* current index into local seps[] */
|
||||
UINT8 rcfg_idx; /* reconfig requested index into sep_info */
|
||||
UINT8 state; /* state machine state */
|
||||
UINT8 avdt_label; /* AVDTP label */
|
||||
UINT8 app_id; /* application id */
|
||||
UINT8 num_recfg; /* number of reconfigure sent */
|
||||
UINT8 role;
|
||||
UINT8 l2c_bufs; /* the number of buffers queued to L2CAP */
|
||||
UINT8 rc_handle; /* connected AVRCP handle */
|
||||
BOOLEAN use_rc; /* TRUE if AVRCP is allowed */
|
||||
BOOLEAN started; /* TRUE if stream started */
|
||||
UINT8 co_started; /* non-zero, if stream started from call-out perspective */
|
||||
BOOLEAN recfg_sup; /* TRUE if the first attempt to reconfigure the stream was successfull, else False if command fails */
|
||||
BOOLEAN suspend_sup; /* TRUE if Suspend stream is supported, else FALSE if suspend command fails */
|
||||
BOOLEAN deregistring; /* TRUE if deregistering */
|
||||
BOOLEAN sco_suspend; /* TRUE if SUSPEND is issued automatically for SCO */
|
||||
UINT8 coll_mask; /* Mask to check incoming and outgoing collision */
|
||||
tBTA_AV_API_OPEN open_api; /* Saved OPEN api message */
|
||||
UINT8 wait; /* set 0x1, when getting Caps as ACP, set 0x2, when started */
|
||||
UINT8 q_tag; /* identify the associated q_info union member */
|
||||
BOOLEAN no_rtp_hdr; /* TRUE if add no RTP header*/
|
||||
UINT8 disc_rsn; /* disconenction reason */
|
||||
UINT16 uuid_int; /*intended UUID of Initiator to connect to */
|
||||
} tBTA_AV_SCB;
|
||||
|
||||
#define BTA_AV_RC_ROLE_MASK 0x10
|
||||
#define BTA_AV_RC_ROLE_INT 0x00
|
||||
#define BTA_AV_RC_ROLE_ACP 0x10
|
||||
|
||||
#define BTA_AV_RC_CONN_MASK 0x20
|
||||
|
||||
/* type for AV RCP control block */
|
||||
/* index to this control block is the rc handle */
|
||||
typedef struct {
|
||||
UINT8 status;
|
||||
UINT8 handle;
|
||||
UINT8 shdl; /* stream handle (hdi + 1) */
|
||||
UINT8 lidx; /* (index+1) to LCB */
|
||||
tBTA_AV_FEAT peer_features; /* peer features mask */
|
||||
} tBTA_AV_RCB;
|
||||
#define BTA_AV_NUM_RCB (BTA_AV_NUM_STRS + 2)
|
||||
|
||||
enum {
|
||||
BTA_AV_LCB_FREE,
|
||||
BTA_AV_LCB_FIND
|
||||
};
|
||||
|
||||
/* type for AV ACL Link control block */
|
||||
typedef struct {
|
||||
BD_ADDR addr; /* peer BD address */
|
||||
UINT8 conn_msk; /* handle mask of connected stream handle */
|
||||
UINT8 lidx; /* index + 1 */
|
||||
} tBTA_AV_LCB;
|
||||
|
||||
/* type for stream state machine action functions */
|
||||
typedef void (*tBTA_AV_SACT)(tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
|
||||
|
||||
/* type for AV control block */
|
||||
typedef struct {
|
||||
tBTA_AV_SCB *p_scb[BTA_AV_NUM_STRS]; /* stream control block */
|
||||
tSDP_DISCOVERY_DB *p_disc_db; /* pointer to discovery database */
|
||||
tBTA_AV_CBACK *p_cback; /* application callback function */
|
||||
tBTA_AV_RCB rcb[BTA_AV_NUM_RCB]; /* RCB control block */
|
||||
tBTA_AV_LCB lcb[BTA_AV_NUM_LINKS + 1]; /* link control block */
|
||||
TIMER_LIST_ENT sig_tmr; /* link timer */
|
||||
TIMER_LIST_ENT acp_sig_tmr; /* timer to monitor signalling when accepting */
|
||||
UINT32 sdp_a2d_handle; /* SDP record handle for audio src */
|
||||
#if (BTA_AV_SINK_INCLUDED == TRUE)
|
||||
UINT32 sdp_a2d_snk_handle; /* SDP record handle for audio snk */
|
||||
#endif
|
||||
UINT32 sdp_vdp_handle; /* SDP record handle for video src */
|
||||
tBTA_AV_FEAT features; /* features mask */
|
||||
tBTA_SEC sec_mask; /* security mask */
|
||||
tBTA_AV_HNDL handle; /* the handle for SDP activity */
|
||||
BOOLEAN disabling; /* TRUE if api disabled called */
|
||||
UINT8 disc; /* (hdi+1) or (rc_handle|BTA_AV_CHNL_MSK) if p_disc_db is in use */
|
||||
UINT8 state; /* state machine state */
|
||||
UINT8 conn_rc; /* handle mask of connected RCP channels */
|
||||
UINT8 conn_audio; /* handle mask of connected audio channels */
|
||||
UINT8 conn_video; /* handle mask of connected video channels */
|
||||
UINT8 conn_lcb; /* index mask of used LCBs */
|
||||
UINT8 audio_open_cnt; /* number of connected audio channels */
|
||||
UINT8 reg_audio; /* handle mask of registered audio channels */
|
||||
UINT8 reg_video; /* handle mask of registered video channels */
|
||||
UINT8 rc_acp_handle;
|
||||
UINT8 rc_acp_idx; /* (index + 1) to RCB */
|
||||
UINT8 rs_idx; /* (index + 1) to SCB for the one waiting for RS on open */
|
||||
BOOLEAN sco_occupied; /* TRUE if SCO is being used or call is in progress */
|
||||
UINT8 audio_streams; /* handle mask of streaming audio channels */
|
||||
UINT8 video_streams; /* handle mask of streaming video channels */
|
||||
} tBTA_AV_CB;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Global data
|
||||
*****************************************************************************/
|
||||
|
||||
/* control block declaration */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
extern tBTA_AV_CB bta_av_cb;
|
||||
#else
|
||||
extern tBTA_AV_CB *bta_av_cb_ptr;
|
||||
#define bta_av_cb (*bta_av_cb_ptr)
|
||||
#endif
|
||||
|
||||
/* config struct */
|
||||
extern tBTA_AV_CFG *p_bta_av_cfg;
|
||||
|
||||
/* rc id config struct */
|
||||
extern UINT16 *p_bta_av_rc_id;
|
||||
extern UINT16 *p_bta_av_rc_id_ac;
|
||||
|
||||
extern const tBTA_AV_SACT bta_av_a2d_action[];
|
||||
// extern const tBTA_AV_CO_FUNCTS bta_av_a2d_cos;
|
||||
extern const tBTA_AV_SACT bta_av_vdp_action[];
|
||||
extern tAVDT_CTRL_CBACK *const bta_av_dt_cback[];
|
||||
extern void bta_av_stream_data_cback(UINT8 handle, BT_HDR *p_pkt, UINT32 time_stamp, UINT8 m_pt);
|
||||
|
||||
/*****************************************************************************
|
||||
** Function prototypes
|
||||
*****************************************************************************/
|
||||
/* utility functions */
|
||||
extern tBTA_AV_SCB *bta_av_hndl_to_scb(UINT16 handle);
|
||||
extern BOOLEAN bta_av_chk_start(tBTA_AV_SCB *p_scb);
|
||||
extern void bta_av_restore_switch (void);
|
||||
extern UINT16 bta_av_chk_mtu(tBTA_AV_SCB *p_scb, UINT16 mtu);
|
||||
extern void bta_av_conn_cback(UINT8 handle, BD_ADDR bd_addr, UINT8 event, tAVDT_CTRL *p_data);
|
||||
extern UINT8 bta_av_rc_create(tBTA_AV_CB *p_cb, UINT8 role, UINT8 shdl, UINT8 lidx);
|
||||
extern void bta_av_stream_chg(tBTA_AV_SCB *p_scb, BOOLEAN started);
|
||||
extern BOOLEAN bta_av_is_scb_opening (tBTA_AV_SCB *p_scb);
|
||||
extern BOOLEAN bta_av_is_scb_incoming (tBTA_AV_SCB *p_scb);
|
||||
extern void bta_av_set_scb_sst_init (tBTA_AV_SCB *p_scb);
|
||||
extern BOOLEAN bta_av_is_scb_init (tBTA_AV_SCB *p_scb);
|
||||
extern void bta_av_set_scb_sst_incoming (tBTA_AV_SCB *p_scb);
|
||||
extern tBTA_AV_LCB *bta_av_find_lcb(BD_ADDR addr, UINT8 op);
|
||||
|
||||
|
||||
/* main functions */
|
||||
extern void bta_av_api_deregister(tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_dup_audio_buf(tBTA_AV_SCB *p_scb, BT_HDR *p_buf);
|
||||
extern void bta_av_sm_execute(tBTA_AV_CB *p_cb, UINT16 event, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_ssm_execute(tBTA_AV_SCB *p_scb, UINT16 event, tBTA_AV_DATA *p_data);
|
||||
extern BOOLEAN bta_av_hdl_event(BT_HDR *p_msg);
|
||||
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
|
||||
extern char *bta_av_evt_code(UINT16 evt_code);
|
||||
#endif
|
||||
extern BOOLEAN bta_av_switch_if_needed(tBTA_AV_SCB *p_scb);
|
||||
extern BOOLEAN bta_av_link_role_ok(tBTA_AV_SCB *p_scb, UINT8 bits);
|
||||
extern BOOLEAN bta_av_is_rcfg_sst(tBTA_AV_SCB *p_scb);
|
||||
|
||||
/* nsm action functions */
|
||||
extern void bta_av_api_disconnect(tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_sig_chg(tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_sig_timer(tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rc_disc_done(tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rc_closed(tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rc_disc(UINT8 disc);
|
||||
extern void bta_av_conn_chg(tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_dereg_comp(tBTA_AV_DATA *p_data);
|
||||
|
||||
/* sm action functions */
|
||||
extern void bta_av_disable (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rc_opened (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rc_remote_cmd (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rc_vendor_cmd (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rc_vendor_rsp (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rc_msg (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rc_close (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rc_meta_rsp (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rc_free_rsp (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rc_free_msg (tBTA_AV_CB *p_cb, tBTA_AV_DATA *p_data);
|
||||
|
||||
extern tBTA_AV_RCB *bta_av_get_rcb_by_shdl(UINT8 shdl);
|
||||
extern void bta_av_del_rc(tBTA_AV_RCB *p_rcb);
|
||||
|
||||
/* ssm action functions */
|
||||
extern void bta_av_do_disc_a2d (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_cleanup (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_free_sdb (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_config_ind (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_disconnect_req (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_security_req (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_security_rsp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_setconfig_rsp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_str_opened (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_security_ind (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_security_cfm (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_do_close (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_connect_req (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_sdp_failed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_disc_results (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_disc_res_as_acp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_open_failed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_getcap_results (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_setconfig_rej (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_discover_req (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_conn_failed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_do_start (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_str_stopped (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_reconfig (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_data_path (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_start_ok (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_start_failed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_str_closed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_clr_cong (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_suspend_cfm (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rcfg_str_ok (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rcfg_failed (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rcfg_connect (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rcfg_discntd (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_suspend_cont (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rcfg_cfm (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rcfg_open (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_security_rej (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_open_rc (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_chk_2nd_start (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_save_caps (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rej_conn (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_rej_conn (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_set_use_rc (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_cco_close (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_switch_role (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_role_res (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_delay_co (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_open_at_inc (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
|
||||
/* ssm action functions - vdp specific */
|
||||
extern void bta_av_do_disc_vdp (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_vdp_str_opened (tBTA_AV_SCB *p_scb, tBTA_AV_DATA *p_data);
|
||||
extern void bta_av_reg_vdp (tAVDT_CS *p_cs, char *p_service_name, void *p_data);
|
||||
|
||||
#endif ///BTA_AV_INCLUDED == TRUE
|
||||
|
||||
#endif /* BTA_AV_INT_H */
|
||||
1351
components/bt/bluedroid/bta/av/bta_av_main.c
Normal file
1351
components/bt/bluedroid/bta/av/bta_av_main.c
Normal file
File diff suppressed because it is too large
Load Diff
614
components/bt/bluedroid/bta/av/bta_av_sbc.c
Normal file
614
components/bt/bluedroid/bta/av/bta_av_sbc.c
Normal file
@@ -0,0 +1,614 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004-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 module contains utility functions for dealing with SBC data frames
|
||||
* and codec capabilities.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
#include "a2d_api.h"
|
||||
#include "a2d_sbc.h"
|
||||
#include "bta_av_sbc.h"
|
||||
#include "utl.h"
|
||||
#include "bt_utils.h"
|
||||
|
||||
#if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE)
|
||||
|
||||
typedef int (tBTA_AV_SBC_ACT)(void *p_src, void *p_dst,
|
||||
UINT32 src_samples, UINT32 dst_samples,
|
||||
UINT32 *p_ret);
|
||||
|
||||
typedef struct {
|
||||
INT32 cur_pos; /* current position */
|
||||
UINT32 src_sps; /* samples per second (source audio data) */
|
||||
UINT32 dst_sps; /* samples per second (converted audio data) */
|
||||
tBTA_AV_SBC_ACT *p_act; /* the action function to do the conversion */
|
||||
UINT16 bits; /* number of bits per pcm sample */
|
||||
UINT16 n_channels; /* number of channels (i.e. mono(1), stereo(2)...) */
|
||||
INT16 worker1;
|
||||
INT16 worker2;
|
||||
UINT8 div;
|
||||
} tBTA_AV_SBC_UPS_CB;
|
||||
|
||||
tBTA_AV_SBC_UPS_CB bta_av_sbc_ups_cb;
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_sbc_init_up_sample
|
||||
**
|
||||
** Description initialize the up sample
|
||||
**
|
||||
** src_sps: samples per second (source audio data)
|
||||
** dst_sps: samples per second (converted audio data)
|
||||
** bits: number of bits per pcm sample
|
||||
** n_channels: number of channels (i.e. mono(1), stereo(2)...)
|
||||
**
|
||||
** Returns none
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_av_sbc_init_up_sample (UINT32 src_sps, UINT32 dst_sps, UINT16 bits, UINT16 n_channels)
|
||||
{
|
||||
bta_av_sbc_ups_cb.cur_pos = -1;
|
||||
bta_av_sbc_ups_cb.src_sps = src_sps;
|
||||
bta_av_sbc_ups_cb.dst_sps = dst_sps;
|
||||
bta_av_sbc_ups_cb.bits = bits;
|
||||
bta_av_sbc_ups_cb.n_channels = n_channels;
|
||||
|
||||
if (n_channels == 1) {
|
||||
/* mono */
|
||||
if (bits == 8) {
|
||||
bta_av_sbc_ups_cb.p_act = bta_av_sbc_up_sample_8m;
|
||||
bta_av_sbc_ups_cb.div = 1;
|
||||
} else {
|
||||
bta_av_sbc_ups_cb.p_act = bta_av_sbc_up_sample_16m;
|
||||
bta_av_sbc_ups_cb.div = 2;
|
||||
}
|
||||
} else {
|
||||
/* stereo */
|
||||
if (bits == 8) {
|
||||
bta_av_sbc_ups_cb.p_act = bta_av_sbc_up_sample_8s;
|
||||
bta_av_sbc_ups_cb.div = 2;
|
||||
} else {
|
||||
bta_av_sbc_ups_cb.p_act = bta_av_sbc_up_sample_16s;
|
||||
bta_av_sbc_ups_cb.div = 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_sbc_up_sample
|
||||
**
|
||||
** Description Given the source (p_src) audio data and
|
||||
** source speed (src_sps, samples per second),
|
||||
** This function converts it to audio data in the desired format
|
||||
**
|
||||
** p_src: the data buffer that holds the source audio data
|
||||
** p_dst: the data buffer to hold the converted audio data
|
||||
** src_samples: The number of source samples (number of bytes)
|
||||
** dst_samples: The size of p_dst (number of bytes)
|
||||
**
|
||||
** Note: An AE reported an issue with this function.
|
||||
** When called with bta_av_sbc_up_sample(src, uint8_array_dst..)
|
||||
** the byte before uint8_array_dst may get overwritten.
|
||||
** Using uint16_array_dst avoids the problem.
|
||||
** This issue is related to endian-ness and is hard to resolve
|
||||
** in a generic manner.
|
||||
** **************** Please use uint16 array as dst.
|
||||
**
|
||||
** Returns The number of bytes used in p_dst
|
||||
** The number of bytes used in p_src (in *p_ret)
|
||||
**
|
||||
*******************************************************************************/
|
||||
int bta_av_sbc_up_sample (void *p_src, void *p_dst,
|
||||
UINT32 src_samples, UINT32 dst_samples,
|
||||
UINT32 *p_ret)
|
||||
{
|
||||
UINT32 src;
|
||||
UINT32 dst;
|
||||
|
||||
if (bta_av_sbc_ups_cb.p_act) {
|
||||
src = src_samples / bta_av_sbc_ups_cb.div;
|
||||
dst = dst_samples / bta_av_sbc_ups_cb.div;
|
||||
return (*bta_av_sbc_ups_cb.p_act)(p_src, p_dst, src, dst, p_ret);
|
||||
} else {
|
||||
*p_ret = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_sbc_up_sample_16s (16bits-stereo)
|
||||
**
|
||||
** Description Given the source (p_src) audio data and
|
||||
** source speed (src_sps, samples per second),
|
||||
** This function converts it to audio data in the desired format
|
||||
**
|
||||
** p_src: the data buffer that holds the source audio data
|
||||
** p_dst: the data buffer to hold the converted audio data
|
||||
** src_samples: The number of source samples (in uint of 4 bytes)
|
||||
** dst_samples: The size of p_dst (in uint of 4 bytes)
|
||||
**
|
||||
** Returns The number of bytes used in p_dst
|
||||
** The number of bytes used in p_src (in *p_ret)
|
||||
**
|
||||
*******************************************************************************/
|
||||
int bta_av_sbc_up_sample_16s (void *p_src, void *p_dst,
|
||||
UINT32 src_samples, UINT32 dst_samples,
|
||||
UINT32 *p_ret)
|
||||
{
|
||||
INT16 *p_src_tmp = (INT16 *)p_src;
|
||||
INT16 *p_dst_tmp = (INT16 *)p_dst;
|
||||
INT16 *p_worker1 = &bta_av_sbc_ups_cb.worker1;
|
||||
INT16 *p_worker2 = &bta_av_sbc_ups_cb.worker2;
|
||||
UINT32 src_sps = bta_av_sbc_ups_cb.src_sps;
|
||||
UINT32 dst_sps = bta_av_sbc_ups_cb.dst_sps;
|
||||
|
||||
while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples) {
|
||||
*p_dst_tmp++ = *p_worker1;
|
||||
*p_dst_tmp++ = *p_worker2;
|
||||
|
||||
bta_av_sbc_ups_cb.cur_pos -= src_sps;
|
||||
dst_samples--;
|
||||
}
|
||||
|
||||
bta_av_sbc_ups_cb.cur_pos = dst_sps;
|
||||
|
||||
while (src_samples-- && dst_samples) {
|
||||
*p_worker1 = *p_src_tmp++;
|
||||
*p_worker2 = *p_src_tmp++;
|
||||
|
||||
do {
|
||||
*p_dst_tmp++ = *p_worker1;
|
||||
*p_dst_tmp++ = *p_worker2;
|
||||
|
||||
bta_av_sbc_ups_cb.cur_pos -= src_sps;
|
||||
dst_samples--;
|
||||
} while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples);
|
||||
|
||||
bta_av_sbc_ups_cb.cur_pos += dst_sps;
|
||||
}
|
||||
|
||||
if (bta_av_sbc_ups_cb.cur_pos == (INT32)dst_sps) {
|
||||
bta_av_sbc_ups_cb.cur_pos = 0;
|
||||
}
|
||||
|
||||
*p_ret = ((char *)p_src_tmp - (char *)p_src);
|
||||
return ((char *)p_dst_tmp - (char *)p_dst);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_sbc_up_sample_16m (16bits-mono)
|
||||
**
|
||||
** Description Given the source (p_src) audio data and
|
||||
** source speed (src_sps, samples per second),
|
||||
** This function converts it to audio data in the desired format
|
||||
**
|
||||
** p_src: the data buffer that holds the source audio data
|
||||
** p_dst: the data buffer to hold the converted audio data
|
||||
** src_samples: The number of source samples (in uint of 2 bytes)
|
||||
** dst_samples: The size of p_dst (in uint of 2 bytes)
|
||||
**
|
||||
** Returns The number of bytes used in p_dst
|
||||
** The number of bytes used in p_src (in *p_ret)
|
||||
**
|
||||
*******************************************************************************/
|
||||
int bta_av_sbc_up_sample_16m (void *p_src, void *p_dst,
|
||||
UINT32 src_samples, UINT32 dst_samples,
|
||||
UINT32 *p_ret)
|
||||
{
|
||||
INT16 *p_src_tmp = (INT16 *)p_src;
|
||||
INT16 *p_dst_tmp = (INT16 *)p_dst;
|
||||
INT16 *p_worker = &bta_av_sbc_ups_cb.worker1;
|
||||
UINT32 src_sps = bta_av_sbc_ups_cb.src_sps;
|
||||
UINT32 dst_sps = bta_av_sbc_ups_cb.dst_sps;
|
||||
|
||||
while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples) {
|
||||
*p_dst_tmp++ = *p_worker;
|
||||
*p_dst_tmp++ = *p_worker;
|
||||
|
||||
bta_av_sbc_ups_cb.cur_pos -= src_sps;
|
||||
dst_samples--;
|
||||
dst_samples--;
|
||||
}
|
||||
|
||||
|
||||
bta_av_sbc_ups_cb.cur_pos = dst_sps;
|
||||
|
||||
while (src_samples-- && dst_samples) {
|
||||
*p_worker = *p_src_tmp++;
|
||||
|
||||
do {
|
||||
*p_dst_tmp++ = *p_worker;
|
||||
*p_dst_tmp++ = *p_worker;
|
||||
|
||||
bta_av_sbc_ups_cb.cur_pos -= src_sps;
|
||||
dst_samples--;
|
||||
dst_samples--;
|
||||
|
||||
} while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples);
|
||||
|
||||
bta_av_sbc_ups_cb.cur_pos += dst_sps;
|
||||
}
|
||||
|
||||
if (bta_av_sbc_ups_cb.cur_pos == (INT32)dst_sps) {
|
||||
bta_av_sbc_ups_cb.cur_pos = 0;
|
||||
}
|
||||
|
||||
*p_ret = ((char *)p_src_tmp - (char *)p_src);
|
||||
return ((char *)p_dst_tmp - (char *)p_dst);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_sbc_up_sample_8s (8bits-stereo)
|
||||
**
|
||||
** Description Given the source (p_src) audio data and
|
||||
** source speed (src_sps, samples per second),
|
||||
** This function converts it to audio data in the desired format
|
||||
**
|
||||
** p_src: the data buffer that holds the source audio data
|
||||
** p_dst: the data buffer to hold the converted audio data
|
||||
** src_samples: The number of source samples (in uint of 2 bytes)
|
||||
** dst_samples: The size of p_dst (in uint of 2 bytes)
|
||||
**
|
||||
** Returns The number of bytes used in p_dst
|
||||
** The number of bytes used in p_src (in *p_ret)
|
||||
**
|
||||
*******************************************************************************/
|
||||
int bta_av_sbc_up_sample_8s (void *p_src, void *p_dst,
|
||||
UINT32 src_samples, UINT32 dst_samples,
|
||||
UINT32 *p_ret)
|
||||
{
|
||||
UINT8 *p_src_tmp = (UINT8 *)p_src;
|
||||
INT16 *p_dst_tmp = (INT16 *)p_dst;
|
||||
INT16 *p_worker1 = &bta_av_sbc_ups_cb.worker1;
|
||||
INT16 *p_worker2 = &bta_av_sbc_ups_cb.worker2;
|
||||
UINT32 src_sps = bta_av_sbc_ups_cb.src_sps;
|
||||
UINT32 dst_sps = bta_av_sbc_ups_cb.dst_sps;
|
||||
|
||||
while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples) {
|
||||
*p_dst_tmp++ = *p_worker1;
|
||||
*p_dst_tmp++ = *p_worker2;
|
||||
|
||||
bta_av_sbc_ups_cb.cur_pos -= src_sps;
|
||||
dst_samples--;
|
||||
dst_samples--;
|
||||
}
|
||||
|
||||
bta_av_sbc_ups_cb.cur_pos = dst_sps;
|
||||
|
||||
while (src_samples -- && dst_samples) {
|
||||
*p_worker1 = *(UINT8 *)p_src_tmp++;
|
||||
*p_worker1 -= 0x80;
|
||||
*p_worker1 <<= 8;
|
||||
*p_worker2 = *(UINT8 *)p_src_tmp++;
|
||||
*p_worker2 -= 0x80;
|
||||
*p_worker2 <<= 8;
|
||||
|
||||
do {
|
||||
*p_dst_tmp++ = *p_worker1;
|
||||
*p_dst_tmp++ = *p_worker2;
|
||||
|
||||
bta_av_sbc_ups_cb.cur_pos -= src_sps;
|
||||
dst_samples--;
|
||||
dst_samples--;
|
||||
} while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples);
|
||||
|
||||
bta_av_sbc_ups_cb.cur_pos += dst_sps;
|
||||
}
|
||||
|
||||
if (bta_av_sbc_ups_cb.cur_pos == (INT32)dst_sps) {
|
||||
bta_av_sbc_ups_cb.cur_pos = 0;
|
||||
}
|
||||
|
||||
*p_ret = ((char *)p_src_tmp - (char *)p_src);
|
||||
return ((char *)p_dst_tmp - (char *)p_dst);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_sbc_up_sample_8m (8bits-mono)
|
||||
**
|
||||
** Description Given the source (p_src) audio data and
|
||||
** source speed (src_sps, samples per second),
|
||||
** This function converts it to audio data in the desired format
|
||||
**
|
||||
** p_src: the data buffer that holds the source audio data
|
||||
** p_dst: the data buffer to hold the converted audio data
|
||||
** src_samples: The number of source samples (number of bytes)
|
||||
** dst_samples: The size of p_dst (number of bytes)
|
||||
**
|
||||
** Returns The number of bytes used in p_dst
|
||||
** The number of bytes used in p_src (in *p_ret)
|
||||
**
|
||||
*******************************************************************************/
|
||||
int bta_av_sbc_up_sample_8m (void *p_src, void *p_dst,
|
||||
UINT32 src_samples, UINT32 dst_samples,
|
||||
UINT32 *p_ret)
|
||||
{
|
||||
UINT8 *p_src_tmp = (UINT8 *)p_src;
|
||||
INT16 *p_dst_tmp = (INT16 *)p_dst;
|
||||
INT16 *p_worker = &bta_av_sbc_ups_cb.worker1;
|
||||
UINT32 src_sps = bta_av_sbc_ups_cb.src_sps;
|
||||
UINT32 dst_sps = bta_av_sbc_ups_cb.dst_sps;
|
||||
|
||||
while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples) {
|
||||
*p_dst_tmp++ = *p_worker;
|
||||
*p_dst_tmp++ = *p_worker;
|
||||
|
||||
bta_av_sbc_ups_cb.cur_pos -= src_sps;
|
||||
dst_samples -= 4;
|
||||
}
|
||||
|
||||
|
||||
bta_av_sbc_ups_cb.cur_pos = dst_sps;
|
||||
|
||||
while (src_samples-- && dst_samples) {
|
||||
*p_worker = *(UINT8 *)p_src_tmp++;
|
||||
*p_worker -= 0x80;
|
||||
*p_worker <<= 8;
|
||||
|
||||
do {
|
||||
*p_dst_tmp++ = *p_worker;
|
||||
*p_dst_tmp++ = *p_worker;
|
||||
|
||||
bta_av_sbc_ups_cb.cur_pos -= src_sps;
|
||||
dst_samples -= 4;
|
||||
|
||||
} while (bta_av_sbc_ups_cb.cur_pos > 0 && dst_samples);
|
||||
|
||||
bta_av_sbc_ups_cb.cur_pos += dst_sps;
|
||||
}
|
||||
|
||||
if (bta_av_sbc_ups_cb.cur_pos == (INT32)dst_sps) {
|
||||
bta_av_sbc_ups_cb.cur_pos = 0;
|
||||
}
|
||||
|
||||
*p_ret = ((char *)p_src_tmp - (char *)p_src);
|
||||
return ((char *)p_dst_tmp - (char *)p_dst);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_sbc_cfg_for_cap
|
||||
**
|
||||
** Description Determine the preferred SBC codec configuration for the
|
||||
** given codec capabilities. The function is passed the
|
||||
** preferred codec configuration and the peer codec
|
||||
** capabilities for the stream. The function attempts to
|
||||
** match the preferred capabilities with the configuration
|
||||
** as best it can. The resulting codec configuration is
|
||||
** returned in the same memory used for the capabilities.
|
||||
**
|
||||
** Returns 0 if ok, nonzero if error.
|
||||
** Codec configuration in p_cap.
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT8 bta_av_sbc_cfg_for_cap(UINT8 *p_peer, tA2D_SBC_CIE *p_cap, tA2D_SBC_CIE *p_pref)
|
||||
{
|
||||
UINT8 status = A2D_SUCCESS;
|
||||
tA2D_SBC_CIE peer_cie;
|
||||
UNUSED(p_cap);
|
||||
|
||||
/* parse peer capabilities */
|
||||
if ((status = A2D_ParsSbcInfo(&peer_cie, p_peer, TRUE)) != 0) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Check if the peer supports our channel mode */
|
||||
if (peer_cie.ch_mode & p_pref->ch_mode) {
|
||||
peer_cie.ch_mode = p_pref->ch_mode;
|
||||
} else {
|
||||
APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: ch_mode(0x%02X) not supported", p_pref->ch_mode);
|
||||
return A2D_FAIL;
|
||||
}
|
||||
|
||||
/* Check if the peer supports our sampling freq */
|
||||
if (peer_cie.samp_freq & p_pref->samp_freq) {
|
||||
peer_cie.samp_freq = p_pref->samp_freq;
|
||||
} else {
|
||||
APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: samp_freq(0x%02X) not supported", p_pref->samp_freq);
|
||||
return A2D_FAIL;
|
||||
}
|
||||
|
||||
/* Check if the peer supports our block len */
|
||||
if (peer_cie.block_len & p_pref->block_len) {
|
||||
peer_cie.block_len = p_pref->block_len;
|
||||
} else {
|
||||
APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: block_len(0x%02X) not supported", p_pref->block_len);
|
||||
return A2D_FAIL;
|
||||
}
|
||||
|
||||
/* Check if the peer supports our num subbands */
|
||||
if (peer_cie.num_subbands & p_pref->num_subbands) {
|
||||
peer_cie.num_subbands = p_pref->num_subbands;
|
||||
} else {
|
||||
APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: num_subbands(0x%02X) not supported", p_pref->num_subbands);
|
||||
return A2D_FAIL;
|
||||
}
|
||||
|
||||
/* Check if the peer supports our alloc method */
|
||||
if (peer_cie.alloc_mthd & p_pref->alloc_mthd) {
|
||||
peer_cie.alloc_mthd = p_pref->alloc_mthd;
|
||||
} else {
|
||||
APPL_TRACE_ERROR("bta_av_sbc_cfg_for_cap: alloc_mthd(0x%02X) not supported", p_pref->alloc_mthd);
|
||||
return A2D_FAIL;
|
||||
}
|
||||
|
||||
/* max bitpool */
|
||||
if (p_pref->max_bitpool != 0 && p_pref->max_bitpool < peer_cie.max_bitpool) {
|
||||
peer_cie.max_bitpool = p_pref->max_bitpool;
|
||||
}
|
||||
|
||||
/* min bitpool */
|
||||
if (p_pref->min_bitpool != 0 && p_pref->min_bitpool > peer_cie.min_bitpool) {
|
||||
peer_cie.min_bitpool = p_pref->min_bitpool;
|
||||
}
|
||||
|
||||
if (status == A2D_SUCCESS) {
|
||||
/* build configuration */
|
||||
A2D_BldSbcInfo(A2D_MEDIA_TYPE_AUDIO, &peer_cie, p_peer);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_sbc_cfg_matches_cap
|
||||
**
|
||||
** Description This function checks whether an SBC codec configuration
|
||||
** matched with capabilities. Here we check subset.
|
||||
**
|
||||
** Returns 0 if ok, nonzero if error.
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT8 bta_av_sbc_cfg_matches_cap(UINT8 *p_cfg, tA2D_SBC_CIE *p_cap)
|
||||
{
|
||||
UINT8 status = 0;
|
||||
tA2D_SBC_CIE cfg_cie;
|
||||
|
||||
/* parse configuration */
|
||||
if ((status = A2D_ParsSbcInfo(&cfg_cie, p_cfg, TRUE)) != 0) {
|
||||
APPL_TRACE_ERROR(" bta_av_sbc_cfg_matches_cap Parsing Failed %d", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* verify that each parameter is in range */
|
||||
|
||||
APPL_TRACE_DEBUG(" FREQ peer: 0%x, capability 0%x", cfg_cie.samp_freq, p_cap->samp_freq);
|
||||
APPL_TRACE_DEBUG(" CH_MODE peer: 0%x, capability 0%x", cfg_cie.ch_mode, p_cap->ch_mode);
|
||||
APPL_TRACE_DEBUG(" BLOCK_LEN peer: 0%x, capability 0%x", cfg_cie.block_len, p_cap->block_len);
|
||||
APPL_TRACE_DEBUG(" SUB_BAND peer: 0%x, capability 0%x", cfg_cie.num_subbands, p_cap->num_subbands);
|
||||
APPL_TRACE_DEBUG(" ALLOC_MTHD peer: 0%x, capability 0%x", cfg_cie.alloc_mthd, p_cap->alloc_mthd);
|
||||
APPL_TRACE_DEBUG(" MAX_BitPool peer: 0%x, capability 0%x", cfg_cie.max_bitpool, p_cap->max_bitpool);
|
||||
APPL_TRACE_DEBUG(" Min_bitpool peer: 0%x, capability 0%x", cfg_cie.min_bitpool, p_cap->min_bitpool);
|
||||
|
||||
/* sampling frequency */
|
||||
if ((cfg_cie.samp_freq & p_cap->samp_freq) == 0) {
|
||||
status = A2D_NS_SAMP_FREQ;
|
||||
}
|
||||
/* channel mode */
|
||||
else if ((cfg_cie.ch_mode & p_cap->ch_mode) == 0) {
|
||||
status = A2D_NS_CH_MODE;
|
||||
}
|
||||
/* block length */
|
||||
else if ((cfg_cie.block_len & p_cap->block_len) == 0) {
|
||||
status = A2D_BAD_BLOCK_LEN;
|
||||
}
|
||||
/* subbands */
|
||||
else if ((cfg_cie.num_subbands & p_cap->num_subbands) == 0) {
|
||||
status = A2D_NS_SUBBANDS;
|
||||
}
|
||||
/* allocation method */
|
||||
else if ((cfg_cie.alloc_mthd & p_cap->alloc_mthd) == 0) {
|
||||
status = A2D_NS_ALLOC_MTHD;
|
||||
}
|
||||
/* max bitpool */
|
||||
else if (cfg_cie.max_bitpool > p_cap->max_bitpool) {
|
||||
status = A2D_NS_MAX_BITPOOL;
|
||||
}
|
||||
/* min bitpool */
|
||||
else if (cfg_cie.min_bitpool < p_cap->min_bitpool) {
|
||||
status = A2D_NS_MIN_BITPOOL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_sbc_cfg_in_cap
|
||||
**
|
||||
** Description This function checks whether an SBC codec configuration
|
||||
** is allowable for the given codec capabilities.
|
||||
**
|
||||
** Returns 0 if ok, nonzero if error.
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT8 bta_av_sbc_cfg_in_cap(UINT8 *p_cfg, tA2D_SBC_CIE *p_cap)
|
||||
{
|
||||
UINT8 status = 0;
|
||||
tA2D_SBC_CIE cfg_cie;
|
||||
|
||||
/* parse configuration */
|
||||
if ((status = A2D_ParsSbcInfo(&cfg_cie, p_cfg, FALSE)) != 0) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* verify that each parameter is in range */
|
||||
|
||||
|
||||
/* sampling frequency */
|
||||
if ((cfg_cie.samp_freq & p_cap->samp_freq) == 0) {
|
||||
status = A2D_NS_SAMP_FREQ;
|
||||
}
|
||||
/* channel mode */
|
||||
else if ((cfg_cie.ch_mode & p_cap->ch_mode) == 0) {
|
||||
status = A2D_NS_CH_MODE;
|
||||
}
|
||||
/* block length */
|
||||
else if ((cfg_cie.block_len & p_cap->block_len) == 0) {
|
||||
status = A2D_BAD_BLOCK_LEN;
|
||||
}
|
||||
/* subbands */
|
||||
else if ((cfg_cie.num_subbands & p_cap->num_subbands) == 0) {
|
||||
status = A2D_NS_SUBBANDS;
|
||||
}
|
||||
/* allocation method */
|
||||
else if ((cfg_cie.alloc_mthd & p_cap->alloc_mthd) == 0) {
|
||||
status = A2D_NS_ALLOC_MTHD;
|
||||
}
|
||||
/* max bitpool */
|
||||
else if (cfg_cie.max_bitpool > p_cap->max_bitpool) {
|
||||
status = A2D_NS_MAX_BITPOOL;
|
||||
}
|
||||
/* min bitpool */
|
||||
else if (cfg_cie.min_bitpool < p_cap->min_bitpool) {
|
||||
status = A2D_NS_MIN_BITPOOL;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_sbc_bld_hdr
|
||||
**
|
||||
** Description This function builds the packet header for MPF1.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_av_sbc_bld_hdr(BT_HDR *p_buf, UINT16 fr_per_pkt)
|
||||
{
|
||||
UINT8 *p;
|
||||
|
||||
p_buf->offset -= BTA_AV_SBC_HDR_SIZE;
|
||||
p = (UINT8 *) (p_buf + 1) + p_buf->offset;
|
||||
p_buf->len += BTA_AV_SBC_HDR_SIZE;
|
||||
A2D_BldSbcMplHdr(p, FALSE, FALSE, FALSE, (UINT8) fr_per_pkt);
|
||||
}
|
||||
|
||||
#endif /* #if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE) */
|
||||
580
components/bt/bluedroid/bta/av/bta_av_ssm.c
Normal file
580
components/bt/bluedroid/bta/av/bta_av_ssm.c
Normal file
@@ -0,0 +1,580 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2004-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 stream state machine for the BTA advanced audio/video.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
#if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE)
|
||||
|
||||
#include <string.h>
|
||||
#include "bta_av_co.h"
|
||||
#include "bta_av_int.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and types
|
||||
*****************************************************************************/
|
||||
|
||||
/* state machine states */
|
||||
enum {
|
||||
BTA_AV_INIT_SST,
|
||||
BTA_AV_INCOMING_SST,
|
||||
BTA_AV_OPENING_SST,
|
||||
BTA_AV_OPEN_SST,
|
||||
BTA_AV_RCFG_SST,
|
||||
BTA_AV_CLOSING_SST
|
||||
};
|
||||
|
||||
|
||||
/* state machine action enumeration list */
|
||||
enum {
|
||||
BTA_AV_DO_DISC,
|
||||
BTA_AV_CLEANUP,
|
||||
BTA_AV_FREE_SDB,
|
||||
BTA_AV_CONFIG_IND,
|
||||
BTA_AV_DISCONNECT_REQ,
|
||||
BTA_AV_SECURITY_REQ,
|
||||
BTA_AV_SECURITY_RSP,
|
||||
BTA_AV_SETCONFIG_RSP,
|
||||
BTA_AV_ST_RC_TIMER,
|
||||
BTA_AV_STR_OPENED,
|
||||
BTA_AV_SECURITY_IND,
|
||||
BTA_AV_SECURITY_CFM,
|
||||
BTA_AV_DO_CLOSE,
|
||||
BTA_AV_CONNECT_REQ,
|
||||
BTA_AV_SDP_FAILED,
|
||||
BTA_AV_DISC_RESULTS,
|
||||
BTA_AV_DISC_RES_AS_ACP,
|
||||
BTA_AV_OPEN_FAILED,
|
||||
BTA_AV_GETCAP_RESULTS,
|
||||
BTA_AV_SETCONFIG_REJ,
|
||||
BTA_AV_DISCOVER_REQ,
|
||||
BTA_AV_CONN_FAILED,
|
||||
BTA_AV_DO_START,
|
||||
BTA_AV_STR_STOPPED,
|
||||
BTA_AV_RECONFIG,
|
||||
BTA_AV_DATA_PATH,
|
||||
BTA_AV_START_OK,
|
||||
BTA_AV_START_FAILED,
|
||||
BTA_AV_STR_CLOSED,
|
||||
BTA_AV_CLR_CONG,
|
||||
BTA_AV_SUSPEND_CFM,
|
||||
BTA_AV_RCFG_STR_OK,
|
||||
BTA_AV_RCFG_FAILED,
|
||||
BTA_AV_RCFG_CONNECT,
|
||||
BTA_AV_RCFG_DISCNTD,
|
||||
BTA_AV_SUSPEND_CONT,
|
||||
BTA_AV_RCFG_CFM,
|
||||
BTA_AV_RCFG_OPEN,
|
||||
BTA_AV_SECURITY_REJ,
|
||||
BTA_AV_OPEN_RC,
|
||||
BTA_AV_CHK_2ND_START,
|
||||
BTA_AV_SAVE_CAPS,
|
||||
BTA_AV_SET_USE_RC,
|
||||
BTA_AV_CCO_CLOSE,
|
||||
BTA_AV_SWITCH_ROLE,
|
||||
BTA_AV_ROLE_RES,
|
||||
BTA_AV_DELAY_CO,
|
||||
BTA_AV_OPEN_AT_INC,
|
||||
BTA_AV_NUM_SACTIONS
|
||||
};
|
||||
|
||||
#define BTA_AV_SIGNORE BTA_AV_NUM_SACTIONS
|
||||
|
||||
|
||||
/* state table information */
|
||||
/* #define BTA_AV_SACTION_COL 0 position of actions */
|
||||
#define BTA_AV_SACTIONS 2 /* number of actions */
|
||||
#define BTA_AV_SNEXT_STATE 2 /* position of next state */
|
||||
#define BTA_AV_NUM_COLS 3 /* number of columns in state tables */
|
||||
|
||||
/* state table for init state */
|
||||
static const UINT8 bta_av_sst_init[][BTA_AV_NUM_COLS] = {
|
||||
/* Event Action 1 Action 2 Next state */
|
||||
/* AP_OPEN_EVT */ {BTA_AV_DO_DISC, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* AP_CLOSE_EVT */ {BTA_AV_CLEANUP, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* AP_START_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* AP_STOP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* API_RECONFIG_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* API_PROTECT_REQ_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* API_PROTECT_RSP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* API_RC_OPEN_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* SRC_DATA_READY_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* CI_SETCONFIG_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* CI_SETCONFIG_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* SDP_DISC_OK_EVT */ {BTA_AV_FREE_SDB, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* SDP_DISC_FAIL_EVT */ {BTA_AV_FREE_SDB, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* STR_DISC_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* STR_DISC_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* STR_GETCAP_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* STR_GETCAP_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* STR_OPEN_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* STR_OPEN_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* STR_START_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* STR_START_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* STR_CLOSE_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* STR_CONFIG_IND_EVT */ {BTA_AV_SETCONFIG_REJ, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* STR_SECURITY_IND_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* STR_SECURITY_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* STR_WRITE_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* STR_SUSPEND_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* STR_RECONFIG_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* AVRC_TIMER_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* AVDT_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* AVDT_DISCONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* ROLE_CHANGE_EVT*/ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* AVDT_DELAY_RPT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* ACP_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST }
|
||||
};
|
||||
|
||||
/* state table for incoming state */
|
||||
static const UINT8 bta_av_sst_incoming[][BTA_AV_NUM_COLS] = {
|
||||
/* Event Action 1 Action 2 Next state */
|
||||
/* AP_OPEN_EVT */ {BTA_AV_OPEN_AT_INC, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* AP_CLOSE_EVT */ {BTA_AV_CCO_CLOSE, BTA_AV_DISCONNECT_REQ, BTA_AV_CLOSING_SST },
|
||||
/* AP_START_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* AP_STOP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* API_RECONFIG_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* API_PROTECT_REQ_EVT */ {BTA_AV_SECURITY_REQ, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* API_PROTECT_RSP_EVT */ {BTA_AV_SECURITY_RSP, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* API_RC_OPEN_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* SRC_DATA_READY_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* CI_SETCONFIG_OK_EVT */ {BTA_AV_SETCONFIG_RSP, BTA_AV_ST_RC_TIMER, BTA_AV_INCOMING_SST },
|
||||
/* CI_SETCONFIG_FAIL_EVT */ {BTA_AV_SETCONFIG_REJ, BTA_AV_CLEANUP, BTA_AV_INIT_SST },
|
||||
/* SDP_DISC_OK_EVT */ {BTA_AV_FREE_SDB, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* SDP_DISC_FAIL_EVT */ {BTA_AV_FREE_SDB, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* STR_DISC_OK_EVT */ {BTA_AV_DISC_RES_AS_ACP, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* STR_DISC_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* STR_GETCAP_OK_EVT */ {BTA_AV_SAVE_CAPS, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* STR_GETCAP_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* STR_OPEN_OK_EVT */ {BTA_AV_STR_OPENED, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* STR_OPEN_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* STR_START_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* STR_START_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* STR_CLOSE_EVT */ {BTA_AV_CCO_CLOSE, BTA_AV_CLEANUP, BTA_AV_INIT_SST },
|
||||
/* STR_CONFIG_IND_EVT */ {BTA_AV_CONFIG_IND, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* STR_SECURITY_IND_EVT */ {BTA_AV_SECURITY_IND, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* STR_SECURITY_CFM_EVT */ {BTA_AV_SECURITY_CFM, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* STR_WRITE_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* STR_SUSPEND_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* STR_RECONFIG_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* AVRC_TIMER_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* AVDT_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* AVDT_DISCONNECT_EVT */ {BTA_AV_CCO_CLOSE, BTA_AV_CLEANUP, BTA_AV_INIT_SST },
|
||||
/* ROLE_CHANGE_EVT*/ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* AVDT_DELAY_RPT_EVT */ {BTA_AV_DELAY_CO, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* ACP_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST }
|
||||
};
|
||||
|
||||
/* state table for opening state */
|
||||
static const UINT8 bta_av_sst_opening[][BTA_AV_NUM_COLS] = {
|
||||
/* Event Action 1 Action 2 Next state */
|
||||
/* AP_OPEN_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* AP_CLOSE_EVT */ {BTA_AV_DO_CLOSE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* AP_START_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* AP_STOP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* API_RECONFIG_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* API_PROTECT_REQ_EVT */ {BTA_AV_SECURITY_REQ, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* API_PROTECT_RSP_EVT */ {BTA_AV_SECURITY_RSP, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* API_RC_OPEN_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* SRC_DATA_READY_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* CI_SETCONFIG_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* CI_SETCONFIG_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* SDP_DISC_OK_EVT */ {BTA_AV_CONNECT_REQ, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* SDP_DISC_FAIL_EVT */ {BTA_AV_CONNECT_REQ, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* STR_DISC_OK_EVT */ {BTA_AV_DISC_RESULTS, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* STR_DISC_FAIL_EVT */ {BTA_AV_OPEN_FAILED, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* STR_GETCAP_OK_EVT */ {BTA_AV_GETCAP_RESULTS, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* STR_GETCAP_FAIL_EVT */ {BTA_AV_OPEN_FAILED, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* STR_OPEN_OK_EVT */ {BTA_AV_ST_RC_TIMER, BTA_AV_STR_OPENED, BTA_AV_OPEN_SST },
|
||||
/* STR_OPEN_FAIL_EVT */ {BTA_AV_OPEN_FAILED, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* STR_START_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* STR_START_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* STR_CLOSE_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* STR_CONFIG_IND_EVT */ {BTA_AV_CONFIG_IND, BTA_AV_SIGNORE, BTA_AV_INCOMING_SST },
|
||||
/* STR_SECURITY_IND_EVT */ {BTA_AV_SECURITY_IND, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* STR_SECURITY_CFM_EVT */ {BTA_AV_SECURITY_CFM, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* STR_WRITE_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* STR_SUSPEND_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* STR_RECONFIG_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* AVRC_TIMER_EVT */ {BTA_AV_SWITCH_ROLE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* AVDT_CONNECT_EVT */ {BTA_AV_DISCOVER_REQ, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* AVDT_DISCONNECT_EVT */ {BTA_AV_CONN_FAILED, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* ROLE_CHANGE_EVT*/ {BTA_AV_ROLE_RES, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* AVDT_DELAY_RPT_EVT */ {BTA_AV_DELAY_CO, BTA_AV_SIGNORE, BTA_AV_OPENING_SST },
|
||||
/* ACP_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPENING_SST }
|
||||
};
|
||||
|
||||
/* state table for open state */
|
||||
static const UINT8 bta_av_sst_open[][BTA_AV_NUM_COLS] = {
|
||||
/* Event Action 1 Action 2 Next state */
|
||||
/* AP_OPEN_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* AP_CLOSE_EVT */ {BTA_AV_DO_CLOSE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* AP_START_EVT */ {BTA_AV_DO_START, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* AP_STOP_EVT */ {BTA_AV_STR_STOPPED, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* API_RECONFIG_EVT */ {BTA_AV_RECONFIG, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* API_PROTECT_REQ_EVT */ {BTA_AV_SECURITY_REQ, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* API_PROTECT_RSP_EVT */ {BTA_AV_SECURITY_RSP, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* API_RC_OPEN_EVT */ {BTA_AV_SET_USE_RC, BTA_AV_OPEN_RC, BTA_AV_OPEN_SST },
|
||||
/* SRC_DATA_READY_EVT */ {BTA_AV_DATA_PATH, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* CI_SETCONFIG_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* CI_SETCONFIG_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* SDP_DISC_OK_EVT */ {BTA_AV_FREE_SDB, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* SDP_DISC_FAIL_EVT */ {BTA_AV_FREE_SDB, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* STR_DISC_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* STR_DISC_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* STR_GETCAP_OK_EVT */ {BTA_AV_SAVE_CAPS, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* STR_GETCAP_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* STR_OPEN_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* STR_OPEN_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* STR_START_OK_EVT */ {BTA_AV_START_OK, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* STR_START_FAIL_EVT */ {BTA_AV_START_FAILED, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* STR_CLOSE_EVT */ {BTA_AV_STR_CLOSED, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* STR_CONFIG_IND_EVT */ {BTA_AV_SETCONFIG_REJ, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* STR_SECURITY_IND_EVT */ {BTA_AV_SECURITY_IND, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* STR_SECURITY_CFM_EVT */ {BTA_AV_SECURITY_CFM, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* STR_WRITE_CFM_EVT */ {BTA_AV_CLR_CONG, BTA_AV_DATA_PATH, BTA_AV_OPEN_SST },
|
||||
/* STR_SUSPEND_CFM_EVT */ {BTA_AV_SUSPEND_CFM, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* STR_RECONFIG_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* AVRC_TIMER_EVT */ {BTA_AV_OPEN_RC, BTA_AV_CHK_2ND_START, BTA_AV_OPEN_SST },
|
||||
/* AVDT_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* AVDT_DISCONNECT_EVT */ {BTA_AV_STR_CLOSED, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* ROLE_CHANGE_EVT*/ {BTA_AV_ROLE_RES, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* AVDT_DELAY_RPT_EVT */ {BTA_AV_DELAY_CO, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* ACP_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_OPEN_SST }
|
||||
};
|
||||
|
||||
/* state table for reconfig state */
|
||||
static const UINT8 bta_av_sst_rcfg[][BTA_AV_NUM_COLS] = {
|
||||
/* Event Action 1 Action 2 Next state */
|
||||
/* AP_OPEN_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* AP_CLOSE_EVT */ {BTA_AV_DISCONNECT_REQ, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* AP_START_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* AP_STOP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* API_RECONFIG_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* API_PROTECT_REQ_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* API_PROTECT_RSP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* API_RC_OPEN_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* SRC_DATA_READY_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* CI_SETCONFIG_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* CI_SETCONFIG_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* SDP_DISC_OK_EVT */ {BTA_AV_FREE_SDB, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* SDP_DISC_FAIL_EVT */ {BTA_AV_FREE_SDB, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* STR_DISC_OK_EVT */ {BTA_AV_DISC_RESULTS, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* STR_DISC_FAIL_EVT */ {BTA_AV_STR_CLOSED, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* STR_GETCAP_OK_EVT */ {BTA_AV_GETCAP_RESULTS, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* STR_GETCAP_FAIL_EVT */ {BTA_AV_STR_CLOSED, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* STR_OPEN_OK_EVT */ {BTA_AV_RCFG_STR_OK, BTA_AV_SIGNORE, BTA_AV_OPEN_SST },
|
||||
/* STR_OPEN_FAIL_EVT */ {BTA_AV_RCFG_FAILED, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* STR_START_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* STR_START_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* STR_CLOSE_EVT */ {BTA_AV_RCFG_CONNECT, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* STR_CONFIG_IND_EVT */ {BTA_AV_SETCONFIG_REJ, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* STR_SECURITY_IND_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* STR_SECURITY_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* STR_WRITE_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* STR_SUSPEND_CFM_EVT */ {BTA_AV_SUSPEND_CONT, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* STR_RECONFIG_CFM_EVT */ {BTA_AV_RCFG_CFM, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* AVRC_TIMER_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* AVDT_CONNECT_EVT */ {BTA_AV_RCFG_OPEN, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* AVDT_DISCONNECT_EVT */ {BTA_AV_RCFG_DISCNTD, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* ROLE_CHANGE_EVT*/ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* AVDT_DELAY_RPT_EVT */ {BTA_AV_DELAY_CO, BTA_AV_SIGNORE, BTA_AV_RCFG_SST },
|
||||
/* ACP_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_RCFG_SST }
|
||||
};
|
||||
|
||||
/* state table for closing state */
|
||||
static const UINT8 bta_av_sst_closing[][BTA_AV_NUM_COLS] = {
|
||||
/* Event Action 1 Action 2 Next state */
|
||||
/* AP_OPEN_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* AP_CLOSE_EVT */ {BTA_AV_DISCONNECT_REQ, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* AP_START_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* AP_STOP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* API_RECONFIG_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* API_PROTECT_REQ_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* API_PROTECT_RSP_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* API_RC_OPEN_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* SRC_DATA_READY_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* CI_SETCONFIG_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* CI_SETCONFIG_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* SDP_DISC_OK_EVT */ {BTA_AV_SDP_FAILED, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* SDP_DISC_FAIL_EVT */ {BTA_AV_SDP_FAILED, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* STR_DISC_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* STR_DISC_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* STR_GETCAP_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* STR_GETCAP_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* STR_OPEN_OK_EVT */ {BTA_AV_DO_CLOSE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* STR_OPEN_FAIL_EVT */ {BTA_AV_DISCONNECT_REQ, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* STR_START_OK_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* STR_START_FAIL_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* STR_CLOSE_EVT */ {BTA_AV_DISCONNECT_REQ, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* STR_CONFIG_IND_EVT */ {BTA_AV_SETCONFIG_REJ, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* STR_SECURITY_IND_EVT */ {BTA_AV_SECURITY_REJ, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* STR_SECURITY_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* STR_WRITE_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* STR_SUSPEND_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* STR_RECONFIG_CFM_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* AVRC_TIMER_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* AVDT_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* AVDT_DISCONNECT_EVT */ {BTA_AV_STR_CLOSED, BTA_AV_SIGNORE, BTA_AV_INIT_SST },
|
||||
/* ROLE_CHANGE_EVT*/ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* AVDT_DELAY_RPT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST },
|
||||
/* ACP_CONNECT_EVT */ {BTA_AV_SIGNORE, BTA_AV_SIGNORE, BTA_AV_CLOSING_SST }
|
||||
};
|
||||
|
||||
/* type for state table */
|
||||
typedef const UINT8 (*tBTA_AV_SST_TBL)[BTA_AV_NUM_COLS];
|
||||
|
||||
/* state table */
|
||||
static const tBTA_AV_SST_TBL bta_av_sst_tbl[] = {
|
||||
bta_av_sst_init,
|
||||
bta_av_sst_incoming,
|
||||
bta_av_sst_opening,
|
||||
bta_av_sst_open,
|
||||
bta_av_sst_rcfg,
|
||||
bta_av_sst_closing
|
||||
};
|
||||
|
||||
|
||||
|
||||
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
|
||||
static char *bta_av_sst_code(UINT8 state);
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_is_rcfg_sst
|
||||
**
|
||||
** Description Check if stream state machine is in reconfig state.
|
||||
**
|
||||
**
|
||||
** Returns TRUE if stream state machine is in reconfig state.
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_av_is_rcfg_sst (tBTA_AV_SCB *p_scb)
|
||||
{
|
||||
BOOLEAN is_rcfg_sst = FALSE;
|
||||
|
||||
if (p_scb != NULL) {
|
||||
if (p_scb->state == BTA_AV_RCFG_SST) {
|
||||
is_rcfg_sst = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return is_rcfg_sst;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_ssm_execute
|
||||
**
|
||||
** Description Stream state machine event handling function for AV
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_av_ssm_execute(tBTA_AV_SCB *p_scb, UINT16 event, tBTA_AV_DATA *p_data)
|
||||
{
|
||||
tBTA_AV_SST_TBL state_table;
|
||||
UINT8 action;
|
||||
int i, xx;
|
||||
|
||||
if (p_scb == NULL) {
|
||||
/* this stream is not registered */
|
||||
APPL_TRACE_EVENT("AV channel not registered");
|
||||
return;
|
||||
}
|
||||
|
||||
/* In case incoming connection is for VDP, we need to swap scb. */
|
||||
/* When ACP_CONNECT_EVT was received, we put first available scb to */
|
||||
/* to Incoming state. Later, when STR_CONFIG_IND_EVT is coming, we */
|
||||
/* know if it is A2DP or VDP. */
|
||||
if ((p_scb->state == BTA_AV_INIT_SST) && (event == BTA_AV_STR_CONFIG_IND_EVT)) {
|
||||
for (xx = 0; xx < BTA_AV_NUM_STRS; xx++) {
|
||||
if (bta_av_cb.p_scb[xx]) {
|
||||
if (bta_av_cb.p_scb[xx]->state == BTA_AV_INCOMING_SST) {
|
||||
bta_av_cb.p_scb[xx]->state = BTA_AV_INIT_SST;
|
||||
bta_av_cb.p_scb[xx]->coll_mask = 0;
|
||||
p_scb->state = BTA_AV_INCOMING_SST;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
|
||||
APPL_TRACE_VERBOSE("AV Sevent(0x%x)=0x%x(%s) state=%d(%s)",
|
||||
p_scb->hndl, event, bta_av_evt_code(event), p_scb->state, bta_av_sst_code(p_scb->state));
|
||||
#else
|
||||
APPL_TRACE_VERBOSE("AV Sevent=0x%x state=%d", event, p_scb->state);
|
||||
#endif
|
||||
|
||||
/* look up the state table for the current state */
|
||||
state_table = bta_av_sst_tbl[p_scb->state];
|
||||
|
||||
event -= BTA_AV_FIRST_SSM_EVT;
|
||||
|
||||
/* set next state */
|
||||
p_scb->state = state_table[event][BTA_AV_SNEXT_STATE];
|
||||
|
||||
/* execute action functions */
|
||||
for (i = 0; i < BTA_AV_SACTIONS; i++) {
|
||||
if ((action = state_table[event][i]) != BTA_AV_SIGNORE) {
|
||||
(*p_scb->p_act_tbl[action])(p_scb, p_data);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_is_scb_opening
|
||||
**
|
||||
** Description Returns TRUE is scb is in opening state.
|
||||
**
|
||||
**
|
||||
** Returns TRUE if scb is in opening state.
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_av_is_scb_opening (tBTA_AV_SCB *p_scb)
|
||||
{
|
||||
BOOLEAN is_opening = FALSE;
|
||||
|
||||
if (p_scb) {
|
||||
if (p_scb->state == BTA_AV_OPENING_SST) {
|
||||
is_opening = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return is_opening;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_is_scb_incoming
|
||||
**
|
||||
** Description Returns TRUE is scb is in incoming state.
|
||||
**
|
||||
**
|
||||
** Returns TRUE if scb is in incoming state.
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_av_is_scb_incoming (tBTA_AV_SCB *p_scb)
|
||||
{
|
||||
BOOLEAN is_incoming = FALSE;
|
||||
|
||||
if (p_scb) {
|
||||
if (p_scb->state == BTA_AV_INCOMING_SST) {
|
||||
is_incoming = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return is_incoming;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_set_scb_sst_init
|
||||
**
|
||||
** Description Set SST state to INIT.
|
||||
** Use this function to change SST outside of state machine.
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_av_set_scb_sst_init (tBTA_AV_SCB *p_scb)
|
||||
{
|
||||
if (p_scb) {
|
||||
p_scb->state = BTA_AV_INIT_SST;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_is_scb_init
|
||||
**
|
||||
** Description Returns TRUE is scb is in init state.
|
||||
**
|
||||
**
|
||||
** Returns TRUE if scb is in incoming state.
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_av_is_scb_init (tBTA_AV_SCB *p_scb)
|
||||
{
|
||||
BOOLEAN is_init = FALSE;
|
||||
|
||||
if (p_scb) {
|
||||
if (p_scb->state == BTA_AV_INIT_SST) {
|
||||
is_init = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return is_init;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_set_scb_sst_incoming
|
||||
**
|
||||
** Description Set SST state to incoming.
|
||||
** Use this function to change SST outside of state machine.
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_av_set_scb_sst_incoming (tBTA_AV_SCB *p_scb)
|
||||
{
|
||||
if (p_scb) {
|
||||
p_scb->state = BTA_AV_INCOMING_SST;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
** Debug Functions
|
||||
*****************************************************************************/
|
||||
#if (defined(BTA_AV_DEBUG) && BTA_AV_DEBUG == TRUE)
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_av_sst_code
|
||||
**
|
||||
** Description
|
||||
**
|
||||
** Returns char *
|
||||
**
|
||||
*******************************************************************************/
|
||||
static char *bta_av_sst_code(UINT8 state)
|
||||
{
|
||||
switch (state) {
|
||||
case BTA_AV_INIT_SST: return "INIT";
|
||||
case BTA_AV_INCOMING_SST: return "INCOMING";
|
||||
case BTA_AV_OPENING_SST: return "OPENING";
|
||||
case BTA_AV_OPEN_SST: return "OPEN";
|
||||
case BTA_AV_RCFG_SST: return "RCFG";
|
||||
case BTA_AV_CLOSING_SST: return "CLOSING";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* BTA_AV_INCLUDED */
|
||||
5662
components/bt/bluedroid/bta/dm/bta_dm_act.c
Normal file
5662
components/bt/bluedroid/bta/dm/bta_dm_act.c
Normal file
File diff suppressed because it is too large
Load Diff
2281
components/bt/bluedroid/bta/dm/bta_dm_api.c
Normal file
2281
components/bt/bluedroid/bta/dm/bta_dm_api.c
Normal file
File diff suppressed because it is too large
Load Diff
581
components/bt/bluedroid/bta/dm/bta_dm_cfg.c
Normal file
581
components/bt/bluedroid/bta/dm/bta_dm_cfg.c
Normal file
@@ -0,0 +1,581 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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
|
||||
};
|
||||
|
||||
#define BTA_DM_PM_SPEC_TO_OFFSET (197) /* timeout offset to avoid conflict with other bluedroid host */
|
||||
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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open sniff */
|
||||
{{BTA_DM_PM_PARK, 5000 + BTA_DM_PM_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_SNIFF_HH_ACTIVE_IDX, BTA_DM_PM_HH_ACTIVE_DELAY + BTA_DM_PM_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
|
||||
{{BTA_DM_PM_SNIFF, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff */
|
||||
{{BTA_DM_PM_SNIFF, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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_SPEC_TO_OFFSET}, {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 && SMP_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
|
||||
1215
components/bt/bluedroid/bta/dm/bta_dm_int.h
Normal file
1215
components/bt/bluedroid/bta/dm/bta_dm_int.h
Normal file
File diff suppressed because it is too large
Load Diff
422
components/bt/bluedroid/bta/dm/bta_dm_main.c
Normal file
422
components/bt/bluedroid/bta/dm/bta_dm_main.c
Normal file
@@ -0,0 +1,422 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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 */
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
/* 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 */
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
/* 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*/
|
||||
#endif ///BTM_SSR_INCLUDED == TRUE
|
||||
/* simple pairing events */
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
bta_dm_confirm, /* 18 BTA_DM_API_CONFIRM_EVT */
|
||||
bta_dm_set_encryption, /* BTA_DM_API_SET_ENCRYPTION_EVT */
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
#if (BTM_OOB_INCLUDED == TRUE && SMP_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
|
||||
#if SMP_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,
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
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 */
|
||||
bta_dm_ble_disconnect, /* BTA_DM_API_BLE_DISCONNECT_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 */
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
BTA_DM_API_DISCOVER, /* 2 bta_dm_discover */
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
BTA_DM_INQUIRY_CMPL, /* 3 bta_dm_inq_cmpl */
|
||||
BTA_DM_REMT_NAME, /* 4 bta_dm_rmt_name */
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
BTA_DM_SDP_RESULT, /* 5 bta_dm_sdp_result */
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
BTA_DM_SEARCH_CMPL, /* 6 bta_dm_search_cmpl*/
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
BTA_DM_FREE_SDP_DB, /* 7 bta_dm_free_sdp_db */
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
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 */
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
BTA_DM_QUEUE_DISC, /* 11 bta_dm_queue_disc */
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
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 */
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL, /* 15 bta_dm_search_cancel_transac_cmpl */
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
BTA_DM_DISC_RMT_NAME, /* 16 bta_dm_disc_rmt_name */
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
BTA_DM_API_DI_DISCOVER, /* 17 bta_dm_di_disc */
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
#if BLE_INCLUDED == TRUE && SDP_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && GATTC_INCLUDED == TRUE
|
||||
BTA_DM_CLOSE_GATT_CONN, /* 18 bta_dm_close_gatt_conn */
|
||||
#endif /* BLE_INCLUDED == TRUE && SDP_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && GATTC_INCLUDED == TRUE */
|
||||
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 */
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
bta_dm_discover, /* 2 BTA_DM_API_DISCOVER */
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
bta_dm_inq_cmpl, /* 3 BTA_DM_INQUIRY_CMPL */
|
||||
bta_dm_rmt_name, /* 4 BTA_DM_REMT_NAME */
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
bta_dm_sdp_result, /* 5 BTA_DM_SDP_RESULT */
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
bta_dm_search_cmpl, /* 6 BTA_DM_SEARCH_CMPL */
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
bta_dm_free_sdp_db, /* 7 BTA_DM_FREE_SDP_DB */
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
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 */
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
bta_dm_queue_disc, /* 11 BTA_DM_QUEUE_DISC */
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
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 */
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
bta_dm_search_cancel_transac_cmpl, /* 15 BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL */
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
bta_dm_disc_rmt_name, /* 16 BTA_DM_DISC_RMT_NAME */
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
bta_dm_di_disc /* 17 BTA_DM_API_DI_DISCOVER */
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
#if BLE_INCLUDED == TRUE && SDP_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && GATTC_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},
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
/* API_SEARCH_DISC */ {BTA_DM_API_DISCOVER, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE},
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
/* 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},
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
/* SDP_RESULT_EVT */ {BTA_DM_FREE_SDP_DB, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
/* 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},
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
/* API_DI_DISCOVER_EVT */ {BTA_DM_API_DI_DISCOVER, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE},
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
#if BLE_INCLUDED == TRUE && SDP_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && GATTC_INCLUDED == TRUE
|
||||
// #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},
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
/* SDP_RESULT_EVT */ {BTA_DM_SDP_RESULT, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE},
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
/* 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 && SDP_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE && GATTC_INCLUDED == TRUE
|
||||
// #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},
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
/* API_SEARCH_DISC */ {BTA_DM_QUEUE_DISC, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_CANCELLING},
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
/* INQUIRY_CMPL */ {BTA_DM_SEARCH_CANCEL_CMPL, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
/* 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},
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
/* 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},
|
||||
#if (SDP_INCLUDED == TRUE)
|
||||
/* SDP_RESULT_EVT */ {BTA_DM_SDP_RESULT, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE},
|
||||
#endif ///SDP_INCLUDED == TRUE
|
||||
/* 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;
|
||||
}
|
||||
|
||||
1166
components/bt/bluedroid/bta/dm/bta_dm_pm.c
Normal file
1166
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
|
||||
2497
components/bt/bluedroid/bta/gatt/bta_gattc_act.c
Normal file
2497
components/bt/bluedroid/bta/gatt/bta_gattc_act.c
Normal file
File diff suppressed because it is too large
Load Diff
1114
components/bt/bluedroid/bta/gatt/bta_gattc_api.c
Normal file
1114
components/bt/bluedroid/bta/gatt/bta_gattc_api.c
Normal file
File diff suppressed because it is too large
Load Diff
1525
components/bt/bluedroid/bta/gatt/bta_gattc_cache.c
Normal file
1525
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(GATTC_INCLUDED) && (GATTC_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 /* GATTC_INCLUDED */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user