forked from espressif/esp-idf
Compare commits
788 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
65f57e5da7 | ||
|
|
5f47b85b87 | ||
|
|
9423390c2e | ||
|
|
f394632319 | ||
|
|
667d0ef319 | ||
|
|
bd20288b81 | ||
|
|
d925b96daf | ||
|
|
df419fd862 | ||
|
|
954ffa102f | ||
|
|
bdf4006da7 | ||
|
|
5c1928b14d | ||
|
|
e0040af7e5 | ||
|
|
c6ec70b67b | ||
|
|
c110795718 | ||
|
|
099e3030bf | ||
|
|
60ac08115f | ||
|
|
6ff431d464 | ||
|
|
9b2cad4174 | ||
|
|
2092d14e45 | ||
|
|
ad555d68d3 | ||
|
|
281a9c2761 | ||
|
|
1abf2c4ed7 | ||
|
|
ba96c0d2e9 | ||
|
|
59f3684dee | ||
|
|
1b9a4a8139 | ||
|
|
144a1567e3 | ||
|
|
7c7f255b98 | ||
|
|
7114f933bb | ||
|
|
72453e3e6b | ||
|
|
a8dd1dfcf2 | ||
|
|
527767d31c | ||
|
|
6010ea713f | ||
|
|
f4df733edf | ||
|
|
d2c61cae8c | ||
|
|
758a9e5f06 | ||
|
|
4c83238a85 | ||
|
|
5a9801aca7 | ||
|
|
5a14e8addf | ||
|
|
9f33d8f5c0 | ||
|
|
f9d2d63e75 | ||
|
|
3a3d4276f8 | ||
|
|
06e2a1d4e1 | ||
|
|
de5279ce6c | ||
|
|
01e94998c4 | ||
|
|
f6de7ea764 | ||
|
|
9d9e758756 | ||
|
|
b9c678f713 | ||
|
|
5b4361f60a | ||
|
|
fc2883a59a | ||
|
|
9a3f9af2db | ||
|
|
72422b32dc | ||
|
|
fd0d28afc3 | ||
|
|
ff8ce12787 | ||
|
|
1173106a20 | ||
|
|
c9a0b9a45c | ||
|
|
db1e86b3d9 | ||
|
|
55aa82f814 | ||
|
|
3f27c09728 | ||
|
|
6e3b7f4ea2 | ||
|
|
73f4e8b2af | ||
|
|
88b264cfce | ||
|
|
a902e2a9de | ||
|
|
ac87ddfb05 | ||
|
|
16f2b119eb | ||
|
|
7f2c6a9d80 | ||
|
|
1818af1c3e | ||
|
|
0dbc11e37d | ||
|
|
58d902eb78 | ||
|
|
d0801fdbab | ||
|
|
9f9d92b2df | ||
|
|
7a93422089 | ||
|
|
7dc322273c | ||
|
|
19273c7b2d | ||
|
|
d7eb709a9c | ||
|
|
a5ad8090cf | ||
|
|
35ae2cd1a5 | ||
|
|
5eb2d16acd | ||
|
|
340b14f0b7 | ||
|
|
1cdd082a9e | ||
|
|
160e81e901 | ||
|
|
b5f03a36d5 | ||
|
|
55e0690f69 | ||
|
|
4ea18083f7 | ||
|
|
b649b48eae | ||
|
|
c17ee8a914 | ||
|
|
1bcd90d45d | ||
|
|
422e95db9c | ||
|
|
7a41ab6982 | ||
|
|
e5ceddabac | ||
|
|
be53a6950c | ||
|
|
79482bbee7 | ||
|
|
f60e54497c | ||
|
|
7e433ae3f4 | ||
|
|
3b937c5ef8 | ||
|
|
f97f198c9d | ||
|
|
6d502cebe9 | ||
|
|
79646f41b5 | ||
|
|
225e31b6de | ||
|
|
452bee7181 | ||
|
|
303ab23116 | ||
|
|
a97e076dec | ||
|
|
6db1482cd5 | ||
|
|
7571b8c2e4 | ||
|
|
c533099e08 | ||
|
|
f7aeef7111 | ||
|
|
13e7e69239 | ||
|
|
ca76f53283 | ||
|
|
9ccb104895 | ||
|
|
85aac3afa6 | ||
|
|
f7fb8b264f | ||
|
|
9ec0fea8e1 | ||
|
|
50f178c1ce | ||
|
|
137c027274 | ||
|
|
38303052f3 | ||
|
|
15d96eccdb | ||
|
|
0b75ff5a6d | ||
|
|
83a3ce882f | ||
|
|
8693e805df | ||
|
|
1d05f41a70 | ||
|
|
180f4d0929 | ||
|
|
5ac7810480 | ||
|
|
a3c4a70ba3 | ||
|
|
2a73783bc6 | ||
|
|
df6edb50e9 | ||
|
|
6cae05d058 | ||
|
|
cf6fc7c741 | ||
|
|
46a39b1e0f | ||
|
|
8b2f933a51 | ||
|
|
2393d829de | ||
|
|
db007fbb2e | ||
|
|
d0c9c1de57 | ||
|
|
190b6d629b | ||
|
|
dfcb241850 | ||
|
|
2561b68af8 | ||
|
|
c48612e516 | ||
|
|
595bd2e3c4 | ||
|
|
d390449371 | ||
|
|
e05fe28574 | ||
|
|
383d987697 | ||
|
|
720a6c1e54 | ||
|
|
46c81ded73 | ||
|
|
4bf0465dab | ||
|
|
cc39b7b286 | ||
|
|
d467eabadb | ||
|
|
235eceea06 | ||
|
|
6a1dbc3f1c | ||
|
|
3b432735c6 | ||
|
|
07fc868ea6 | ||
|
|
1cc1d9d721 | ||
|
|
1ca82de638 | ||
|
|
4261fc5ef7 | ||
|
|
7681dbec93 | ||
|
|
39e924b664 | ||
|
|
586c17f831 | ||
|
|
4079d1e008 | ||
|
|
1d47755588 | ||
|
|
fc6be12a8f | ||
|
|
9cc9710a27 | ||
|
|
4ed6404e9f | ||
|
|
ed0612c56b | ||
|
|
a485af0e2d | ||
|
|
bf20b958a9 | ||
|
|
c6016952e8 | ||
|
|
a8fb9f2b84 | ||
|
|
311a4cd678 | ||
|
|
d4b5bd347d | ||
|
|
dd0585e84e | ||
|
|
a86c431f98 | ||
|
|
bf61f6de55 | ||
|
|
4e9e8f52ac | ||
|
|
fa3e4103ab | ||
|
|
4d81e40413 | ||
|
|
8cd48d9f9c | ||
|
|
1561c02ba9 | ||
|
|
fa57720cdf | ||
|
|
a76b65ed95 | ||
|
|
b08113d2b4 | ||
|
|
ab92d43bc6 | ||
|
|
0245a2028c | ||
|
|
659ec8facb | ||
|
|
139fdcb9ec | ||
|
|
4dcf3709b0 | ||
|
|
5a81c06e39 | ||
|
|
1f6585dd4f | ||
|
|
0b265dc2a7 | ||
|
|
541b142654 | ||
|
|
6d4ab76db2 | ||
|
|
4db29f74a0 | ||
|
|
a0feea8daa | ||
|
|
6e97936bac | ||
|
|
51021b06f8 | ||
|
|
3edcd29a83 | ||
|
|
2f7288ff03 | ||
|
|
8ab4e11840 | ||
|
|
1cc0b3000b | ||
|
|
36f29017b6 | ||
|
|
68d370542a | ||
|
|
f87be70d51 | ||
|
|
6b687b43f4 | ||
|
|
2b196b4f3e | ||
|
|
37365cef95 | ||
|
|
645717b147 | ||
|
|
b092e42740 | ||
|
|
f3a44aa4db | ||
|
|
7548b8c622 | ||
|
|
3bbe41c34d | ||
|
|
e332407785 | ||
|
|
d73448f57f | ||
|
|
acafa9aaa8 | ||
|
|
b0ca2feabc | ||
|
|
9e6e6b8ff6 | ||
|
|
6472f193ab | ||
|
|
02f5bb9442 | ||
|
|
d116adf260 | ||
|
|
d19d7107d3 | ||
|
|
3366c98d39 | ||
|
|
b0f3b730aa | ||
|
|
936b02216b | ||
|
|
2ab64e1ecc | ||
|
|
12dd886ee1 | ||
|
|
a35e2d42f0 | ||
|
|
f12be7ebd8 | ||
|
|
5e428f21b6 | ||
|
|
ceea97495f | ||
|
|
78d0849426 | ||
|
|
872a481cf1 | ||
|
|
84635a160e | ||
|
|
24b4c17ead | ||
|
|
4eeb2bc41e | ||
|
|
c90e3c7f9e | ||
|
|
637f6fb27e | ||
|
|
13d4734399 | ||
|
|
ca202cbb46 | ||
|
|
8713155e66 | ||
|
|
94f26af17d | ||
|
|
aafaebefb4 | ||
|
|
0b2cea6e9f | ||
|
|
a63383dd19 | ||
|
|
a023b005c6 | ||
|
|
dd3c8487f1 | ||
|
|
19d96d5b26 | ||
|
|
9691fe9dae | ||
|
|
69dbc36a1c | ||
|
|
8b7d1cdc27 | ||
|
|
d1fc5fe432 | ||
|
|
13b81debb3 | ||
|
|
37cbb0bdea | ||
|
|
7dbf01b210 | ||
|
|
60f29236f6 | ||
|
|
8fed003ce5 | ||
|
|
9ae07082ff | ||
|
|
2ed9e2d9a8 | ||
|
|
656543c5ca | ||
|
|
21d2b78105 | ||
|
|
d7599ab16d | ||
|
|
229df65cfc | ||
|
|
521ef3f579 | ||
|
|
cf8c9770a0 | ||
|
|
4d25986aaa | ||
|
|
a2b1f4221b | ||
|
|
dfaac25a37 | ||
|
|
a40e0936e5 | ||
|
|
a8a51a2786 | ||
|
|
0e69a2c446 | ||
|
|
1b25795f5d | ||
|
|
078a16f7b4 | ||
|
|
9a2887c458 | ||
|
|
aa81f047f8 | ||
|
|
3bf5fb8ae7 | ||
|
|
fa1d5bfbc7 | ||
|
|
42787948bb | ||
|
|
adb4be859c | ||
|
|
858fe9815b | ||
|
|
64a2f0ee0b | ||
|
|
c694c5134f | ||
|
|
c36a3e7d06 | ||
|
|
c625f0e906 | ||
|
|
794b4ff578 | ||
|
|
9a7db9ca85 | ||
|
|
751736f902 | ||
|
|
f7af4ddc89 | ||
|
|
2bad1dd594 | ||
|
|
c04f05ee84 | ||
|
|
c15024e629 | ||
|
|
ea4005e673 | ||
|
|
09c7ccfa2c | ||
|
|
0b4fe9dd6d | ||
|
|
572f62928b | ||
|
|
045a53a7e5 | ||
|
|
6eac435723 | ||
|
|
734c1dd954 | ||
|
|
8691b54758 | ||
|
|
bcdebda8e4 | ||
|
|
5a5e19cd8b | ||
|
|
e459f803da | ||
|
|
fe66dd85f0 | ||
|
|
ff1b2c6039 | ||
|
|
7402a1b973 | ||
|
|
64f3893cb9 | ||
|
|
b5de581399 | ||
|
|
f9e9e6b938 | ||
|
|
cc510c1d95 | ||
|
|
57009aaa7f | ||
|
|
f5cebd2666 | ||
|
|
980be385cb | ||
|
|
fdf3db1959 | ||
|
|
9aa9086c8b | ||
|
|
7b77daaea4 | ||
|
|
8dc9e243ae | ||
|
|
177bb340b3 | ||
|
|
341593f7d2 | ||
|
|
ce0382f0c0 | ||
|
|
9858fde4a2 | ||
|
|
48a976ddbf | ||
|
|
c6073cb5de | ||
|
|
08fd07a1ef | ||
|
|
71940dd0ce | ||
|
|
2f6d71ff8c | ||
|
|
eb067ce908 | ||
|
|
07c30f22b5 | ||
|
|
86d8f63005 | ||
|
|
4f4c9030fd | ||
|
|
3269653b94 | ||
|
|
e94ef1d56e | ||
|
|
07f36a9437 | ||
|
|
25db1effd6 | ||
|
|
3aca537157 | ||
|
|
f7cb6fc969 | ||
|
|
208e83def7 | ||
|
|
6fb2515a5d | ||
|
|
f1938a909a | ||
|
|
c441d3630c | ||
|
|
2f0efe1510 | ||
|
|
3b96f68afd | ||
|
|
d7e57eb668 | ||
|
|
155f912433 | ||
|
|
830e5caf4d | ||
|
|
fcba7e278d | ||
|
|
0dff62051f | ||
|
|
cc072f1d8a | ||
|
|
c5793521a0 | ||
|
|
81b18aa8d5 | ||
|
|
1e4f185d29 | ||
|
|
f142da3ced | ||
|
|
d29935b9ce | ||
|
|
6dd3681115 | ||
|
|
3f8d9d71e2 | ||
|
|
aa0cd0ab47 | ||
|
|
13b3c916f3 | ||
|
|
bdd7fb7a13 | ||
|
|
2dda3f57b5 | ||
|
|
cdebf24954 | ||
|
|
8dee0a3f6d | ||
|
|
c3eee0fa52 | ||
|
|
414e5ce1d5 | ||
|
|
cb5f7690a4 | ||
|
|
0aca2506fc | ||
|
|
7340a77689 | ||
|
|
1418f886eb | ||
|
|
178db4bdd9 | ||
|
|
d12078b692 | ||
|
|
fce359b240 | ||
|
|
98a0387854 | ||
|
|
0762b050dd | ||
|
|
314cbcdb67 | ||
|
|
e452278194 | ||
|
|
c8a43508e5 | ||
|
|
b6dd8a55cd | ||
|
|
4e1c56e965 | ||
|
|
599a65657d | ||
|
|
faad29234a | ||
|
|
118984283a | ||
|
|
025bb47302 | ||
|
|
3b489f04f0 | ||
|
|
522f83ae3d | ||
|
|
3051c74488 | ||
|
|
d093dcbbb7 | ||
|
|
c3f7d15246 | ||
|
|
3eaf1ec907 | ||
|
|
7bcd68fb30 | ||
|
|
adca98348e | ||
|
|
9c2ab4559d | ||
|
|
b981b195be | ||
|
|
224acf37f6 | ||
|
|
084248e211 | ||
|
|
5c3ce5b269 | ||
|
|
aa6fe04148 | ||
|
|
acda125e8b | ||
|
|
4ea38327b6 | ||
|
|
b83b0ed06a | ||
|
|
1544965b21 | ||
|
|
8089afd453 | ||
|
|
2d88fc0329 | ||
|
|
90d9f1a74e | ||
|
|
3ec23f1b83 | ||
|
|
2fa00ebd90 | ||
|
|
8bdcf0c5f7 | ||
|
|
15474b9b7e | ||
|
|
a6b3be6734 | ||
|
|
9ed7c4f8bc | ||
|
|
e96d4a0a32 | ||
|
|
e314f42b0c | ||
|
|
4d3ed9efde | ||
|
|
b717e44eb2 | ||
|
|
6602d6b7f2 | ||
|
|
8282c73ac2 | ||
|
|
abecab7525 | ||
|
|
bc4f1c90a7 | ||
|
|
299655e3be | ||
|
|
1540469598 | ||
|
|
c377650cdd | ||
|
|
5035f51c4e | ||
|
|
eb2c633cbf | ||
|
|
47910466ce | ||
|
|
e56b745527 | ||
|
|
c12aeb1127 | ||
|
|
2e319705ec | ||
|
|
fdff6b2b01 | ||
|
|
57f8128718 | ||
|
|
cdd65095e3 | ||
|
|
bc604d14ff | ||
|
|
c534dedf2d | ||
|
|
0aadc58b87 | ||
|
|
a0007ceb79 | ||
|
|
aceb6517c0 | ||
|
|
2cea783ca1 | ||
|
|
97c75a88ae | ||
|
|
3af7872839 | ||
|
|
d0fac3c395 | ||
|
|
04beb8baba | ||
|
|
4ba1b73eba | ||
|
|
cf732bb663 | ||
|
|
f10cc7dc8e | ||
|
|
1cab448c73 | ||
|
|
e1f0c98ef5 | ||
|
|
0df0d74d5d | ||
|
|
f18c1f13b1 | ||
|
|
b8e940d645 | ||
|
|
fe64ea95b4 | ||
|
|
d76868eec1 | ||
|
|
4f71d741ec | ||
|
|
c67ac340c7 | ||
|
|
1d3626c119 | ||
|
|
5784586041 | ||
|
|
bc834820bb | ||
|
|
d472ff5856 | ||
|
|
8c1d1e19c2 | ||
|
|
edf5b10344 | ||
|
|
f0cd38a079 | ||
|
|
12e78e9590 | ||
|
|
bc710e5b88 | ||
|
|
66b31b89ac | ||
|
|
cb33e2a5ae | ||
|
|
8d1f360ca6 | ||
|
|
16a4d56fe5 | ||
|
|
fc6b52574a | ||
|
|
c85be70b9f | ||
|
|
a8b2608dd9 | ||
|
|
ce9e73cd19 | ||
|
|
8d6b782327 | ||
|
|
73944e6800 | ||
|
|
d66f05c61b | ||
|
|
12efd96fb4 | ||
|
|
19af5b7a76 | ||
|
|
079f5faad8 | ||
|
|
f6118c67b0 | ||
|
|
905d27815c | ||
|
|
2d56953ee4 | ||
|
|
fa002b4909 | ||
|
|
234739f51a | ||
|
|
1263cd340e | ||
|
|
f05cd619f4 | ||
|
|
adae42fd85 | ||
|
|
591b7caa95 | ||
|
|
3584fcfc7c | ||
|
|
b6a463e94f | ||
|
|
8ae97a2855 | ||
|
|
6ce1af5898 | ||
|
|
4900c63071 | ||
|
|
6435a71de2 | ||
|
|
cb70ac831f | ||
|
|
99fc760088 | ||
|
|
ec99397c3e | ||
|
|
41514f497a | ||
|
|
124a673a78 | ||
|
|
92b663d9f2 | ||
|
|
abea6c50f1 | ||
|
|
c7f8d206ed | ||
|
|
d9cdc7de58 | ||
|
|
2b722ea468 | ||
|
|
19f61332a9 | ||
|
|
1cc3858dc8 | ||
|
|
413f2c00f6 | ||
|
|
269332f473 | ||
|
|
2119b98469 | ||
|
|
3053518f8a | ||
|
|
d7b4197ade | ||
|
|
a5552b1e21 | ||
|
|
e34fc7a46c | ||
|
|
e7cc1aded5 | ||
|
|
9555ce291e | ||
|
|
41a91d7cb9 | ||
|
|
2d15803f70 | ||
|
|
f30887bc70 | ||
|
|
ffeffcd315 | ||
|
|
90b787636a | ||
|
|
4f2719236f | ||
|
|
19c4996bc8 | ||
|
|
5ffd6155f2 | ||
|
|
0e90983c9f | ||
|
|
0933339e4b | ||
|
|
95403b8803 | ||
|
|
3cd86d6bce | ||
|
|
78392bf76b | ||
|
|
309bd12855 | ||
|
|
d6db871068 | ||
|
|
a038a2b533 | ||
|
|
9e7bc900c5 | ||
|
|
38ff616e4a | ||
|
|
4d8ad3c877 | ||
|
|
305b63209e | ||
|
|
933b6bd94a | ||
|
|
dc2b5d0c96 | ||
|
|
c581229e1d | ||
|
|
9f0f05d520 | ||
|
|
e03b45eb0a | ||
|
|
e229ec0340 | ||
|
|
b6693225c1 | ||
|
|
2c5340d47e | ||
|
|
079d9ea018 | ||
|
|
999e6d4e8f | ||
|
|
42068c3b36 | ||
|
|
54ca573ce4 | ||
|
|
628bde2080 | ||
|
|
f6f23141b3 | ||
|
|
bdf2908057 | ||
|
|
6f1d3ce4a7 | ||
|
|
da56e76255 | ||
|
|
7e201c5527 | ||
|
|
0c130ecf19 | ||
|
|
b3b8334d54 | ||
|
|
587360363c | ||
|
|
401f6e4713 | ||
|
|
38c6256db9 | ||
|
|
68f39c1ed9 | ||
|
|
b14faabfda | ||
|
|
3371083c16 | ||
|
|
84c2e61b12 | ||
|
|
6e6e51426f | ||
|
|
cc7313f216 | ||
|
|
50bd28353d | ||
|
|
329ad14b8c | ||
|
|
c6477ff10d | ||
|
|
95d0ea0d98 | ||
|
|
ff6b8addd9 | ||
|
|
e0f49c2221 | ||
|
|
fd887dbeea | ||
|
|
8dcd78d52f | ||
|
|
6d54fb004d | ||
|
|
5642a8061e | ||
|
|
df1c2f0da5 | ||
|
|
d3d9a8bc28 | ||
|
|
5ede46f213 | ||
|
|
750d6faf51 | ||
|
|
345cf333a8 | ||
|
|
3cd8149288 | ||
|
|
3cca62dfa4 | ||
|
|
a799bb8519 | ||
|
|
7847569672 | ||
|
|
45638b3f98 | ||
|
|
9546ad5b5e | ||
|
|
a90217e201 | ||
|
|
48301909eb | ||
|
|
612aaa69e4 | ||
|
|
74a658c765 | ||
|
|
bb1efe50c3 | ||
|
|
7d254eb3f0 | ||
|
|
fd064e5d88 | ||
|
|
47d73dfe05 | ||
|
|
1ca97f5adb | ||
|
|
6f96b23989 | ||
|
|
86dc0ae808 | ||
|
|
06bff71481 | ||
|
|
89f7752cdd | ||
|
|
78d1fd5306 | ||
|
|
75a11589a1 | ||
|
|
20d33d636b | ||
|
|
cbb26c9532 | ||
|
|
700ed63651 | ||
|
|
d7ea61734b | ||
|
|
d9005e739d | ||
|
|
8e247f3b4c | ||
|
|
3edcf5b096 | ||
|
|
abd4dc7d43 | ||
|
|
5fbfa2a01d | ||
|
|
be11f598bf | ||
|
|
74aff2b9d2 | ||
|
|
f988dc9587 | ||
|
|
9098e64398 | ||
|
|
288f4f63f0 | ||
|
|
60fb9a8c81 | ||
|
|
ae5c563080 | ||
|
|
beff3aab81 | ||
|
|
2b8a493659 | ||
|
|
53146799a0 | ||
|
|
922839d131 | ||
|
|
063e9e8287 | ||
|
|
2c0ceb484b | ||
|
|
1413ec3ff0 | ||
|
|
f37e70ebd6 | ||
|
|
94442708f5 | ||
|
|
8e8caca2e2 | ||
|
|
42827ff869 | ||
|
|
7104284e31 | ||
|
|
4f704ac2fe | ||
|
|
feca308f1f | ||
|
|
6b85040059 | ||
|
|
dfe0dcaed4 | ||
|
|
d3d8c04535 | ||
|
|
39a06319e2 | ||
|
|
0704deca63 | ||
|
|
ede25dbc17 | ||
|
|
5e8849d032 | ||
|
|
2d393f0530 | ||
|
|
c350972eac | ||
|
|
e81ff4f68c | ||
|
|
18ebc6411e | ||
|
|
6eaf595a0e | ||
|
|
0324373cd1 | ||
|
|
c2b63a614e | ||
|
|
de7b2f5a09 | ||
|
|
3f521c4afa | ||
|
|
fcf664276f | ||
|
|
da70611196 | ||
|
|
24df5e2041 | ||
|
|
2182b69b3d | ||
|
|
746ad41d89 | ||
|
|
90cad92b9b | ||
|
|
340a722715 | ||
|
|
19db9ed870 | ||
|
|
d00ef1607e | ||
|
|
0574f2f55a | ||
|
|
9476dc2eb8 | ||
|
|
6a7ec425cb | ||
|
|
c03549e117 | ||
|
|
0403d43b19 | ||
|
|
28d83e766a | ||
|
|
8f82a83c2c | ||
|
|
28fa3c1a70 | ||
|
|
2fdd9ba930 | ||
|
|
eaace9846a | ||
|
|
bee1be67da | ||
|
|
34fa6a60a9 | ||
|
|
1cd572c7b9 | ||
|
|
182184567e | ||
|
|
0aab006bb7 | ||
|
|
7cb55c2c6c | ||
|
|
3ed2d89538 | ||
|
|
f87ebb6d49 | ||
|
|
3ecce07dbc | ||
|
|
1a08abea78 | ||
|
|
02ad223eea | ||
|
|
982b90e77d | ||
|
|
4370794d07 | ||
|
|
72712c00a7 | ||
|
|
f68c8dd687 | ||
|
|
af9b08d863 | ||
|
|
216b831646 | ||
|
|
65445b21dd | ||
|
|
bdd67c98d6 | ||
|
|
6a5f5400f0 | ||
|
|
20b508e62e | ||
|
|
fa476c8ba9 | ||
|
|
03bd5b6d22 | ||
|
|
89097d5f11 | ||
|
|
c56325f43b | ||
|
|
3c792f427b | ||
|
|
ce7b8059de | ||
|
|
9632c8e56c | ||
|
|
6b3bc4d8c5 | ||
|
|
1a6dd44d03 | ||
|
|
5e0a9bfcf2 | ||
|
|
e9199a0320 | ||
|
|
b72d22041c | ||
|
|
d85ff46bdf | ||
|
|
849ba39544 | ||
|
|
685c1084ba | ||
|
|
1447cd4136 | ||
|
|
e5b8854d96 | ||
|
|
19ca66c968 | ||
|
|
fbb654fa68 | ||
|
|
6442601333 | ||
|
|
12fa7472ea | ||
|
|
547fb6ed6c | ||
|
|
9b72441b45 | ||
|
|
4929534448 | ||
|
|
d7db3e6a35 | ||
|
|
5ba6c1b1b7 | ||
|
|
5fab6c36c8 | ||
|
|
d695d40196 | ||
|
|
59b35eb16a | ||
|
|
024a1ce260 | ||
|
|
4de2054541 | ||
|
|
745ecef263 | ||
|
|
99ebc93abb | ||
|
|
e2dd6ebcf0 | ||
|
|
2fe759ce1d | ||
|
|
90e57cdf8f | ||
|
|
924fea7cc0 | ||
|
|
8ee1a05914 | ||
|
|
58aec93dbb | ||
|
|
609c1c2cdb | ||
|
|
1bae606ccc | ||
|
|
c12582c122 | ||
|
|
79bd6af7e7 | ||
|
|
71c09d8f66 | ||
|
|
a20c2f1088 | ||
|
|
ab67378ef3 | ||
|
|
812d4ab4ea | ||
|
|
bde768f13c | ||
|
|
0b30c22162 | ||
|
|
833eb88679 | ||
|
|
e32d4e546a | ||
|
|
5d60a1153d | ||
|
|
ecefb1305a | ||
|
|
034da95abb | ||
|
|
37a68ad605 | ||
|
|
47e83ee65e | ||
|
|
2033068a72 | ||
|
|
d71894bf99 | ||
|
|
df31bb8dfc | ||
|
|
82df5f9aa0 | ||
|
|
a03e75d34c | ||
|
|
5cd3bd5c4b | ||
|
|
eb8cb8d22e | ||
|
|
1c877be609 | ||
|
|
0b37621438 | ||
|
|
12caaed280 | ||
|
|
aae3e84829 | ||
|
|
305bc9fd9c | ||
|
|
6a890e6c49 | ||
|
|
f720e82d40 | ||
|
|
eccf54b939 | ||
|
|
477d71e589 | ||
|
|
66882347e8 | ||
|
|
9c0cd10d48 | ||
|
|
7bdcafe553 | ||
|
|
de587a2e0d | ||
|
|
b97c00f2c1 | ||
|
|
1bcc5438ec | ||
|
|
9c4e43a3a5 | ||
|
|
6c793cb8eb | ||
|
|
9e20d31f89 | ||
|
|
6941b5871a | ||
|
|
877adaab7a | ||
|
|
652ddae44f | ||
|
|
3882937427 | ||
|
|
b80325604d | ||
|
|
cf4aaf6397 | ||
|
|
e1c4a4bfa3 | ||
|
|
d2bc170b86 | ||
|
|
83aea6c833 | ||
|
|
12b72e91af | ||
|
|
5c5f7eb7fe | ||
|
|
f9fd5b6c72 | ||
|
|
59bb9a9a01 | ||
|
|
db9becfa74 | ||
|
|
e475d0539e | ||
|
|
f5d9bfc7ae | ||
|
|
07c8bbca6c | ||
|
|
9fc054bb55 | ||
|
|
1bfedf9816 | ||
|
|
18787fd4fc | ||
|
|
f796b4e58e | ||
|
|
fa6f03f77f | ||
|
|
a99f6bd727 | ||
|
|
2faa2376a0 | ||
|
|
6f07409d7c | ||
|
|
b3145446aa | ||
|
|
2cc32db52d | ||
|
|
01d17dd5f9 | ||
|
|
c504fe4856 | ||
|
|
845ca8b34f | ||
|
|
6bd3d62d7c | ||
|
|
b89168d0f1 | ||
|
|
5adc661d05 | ||
|
|
44c466c0ea | ||
|
|
db2da43fc1 |
11
.gitignore
vendored
11
.gitignore
vendored
@@ -20,5 +20,12 @@ examples/*/sdkconfig
|
||||
examples/*/sdkconfig.old
|
||||
examples/*/build
|
||||
|
||||
# Bootloader files
|
||||
components/bootloader/src/sdkconfig.old
|
||||
#Doc build artifacts
|
||||
docs/_build/
|
||||
docs/doxygen-warning-log.txt
|
||||
docs/xml/
|
||||
|
||||
# Unit test app files
|
||||
tools/unit-test-app/sdkconfig
|
||||
tools/unit-test-app/sdkconfig.old
|
||||
tools/unit-test-app/build
|
||||
|
||||
375
.gitlab-ci.yml
375
.gitlab-ci.yml
@@ -1,6 +1,8 @@
|
||||
stages:
|
||||
- build
|
||||
- unit_test
|
||||
- test
|
||||
- test_report
|
||||
- deploy
|
||||
|
||||
before_script:
|
||||
@@ -37,7 +39,17 @@ build_template_app:
|
||||
# branch
|
||||
- git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..."
|
||||
- make defconfig
|
||||
# Test debug build (default)
|
||||
- make all V=1
|
||||
# Now test release build
|
||||
- make clean
|
||||
- sed -i.bak -e's/CONFIG_OPTIMIZATION_LEVEL_DEBUG\=y/CONFIG_OPTIMIZATION_LEVEL_RELEASE=y/' sdkconfig
|
||||
- make defconfig
|
||||
- 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
|
||||
@@ -55,20 +67,33 @@ build_ssc:
|
||||
<<: *build_template
|
||||
artifacts:
|
||||
paths:
|
||||
- ./SSC/build/*.bin
|
||||
- ./SSC/build/*.elf
|
||||
- ./SSC/build/*.map
|
||||
- ./SSC/build/bootloader/*.bin
|
||||
- ./SSC/ssc_bin
|
||||
expire_in: 6 mos
|
||||
|
||||
script:
|
||||
- git clone ssh://git@gitlab.espressif.cn:27227/yinling/SSC.git
|
||||
- git clone $GITLAB_SSH_SERVER/yinling/SSC.git
|
||||
- cd SSC
|
||||
- git checkout ${CI_BUILD_REF_NAME} || echo "Using SSC default branch..."
|
||||
- make defconfig
|
||||
- chmod +x gen_misc_ng.sh
|
||||
- ./gen_misc_ng.sh
|
||||
|
||||
build_esp_idf_tests:
|
||||
<<: *build_template
|
||||
artifacts:
|
||||
paths:
|
||||
- ./tools/unit-test-app/build/*.bin
|
||||
- ./tools/unit-test-app/build/*.elf
|
||||
- ./tools/unit-test-app/build/*.map
|
||||
- ./tools/unit-test-app/build/bootloader/*.bin
|
||||
expire_in: 6 mos
|
||||
|
||||
script:
|
||||
- cd tools/unit-test-app
|
||||
- git checkout ${CI_BUILD_REF_NAME} || echo "Using default branch..."
|
||||
- make defconfig
|
||||
- make TESTS_ALL=1
|
||||
|
||||
build_examples:
|
||||
<<: *build_template
|
||||
artifacts:
|
||||
@@ -86,13 +111,30 @@ build_examples:
|
||||
- cd build_examples
|
||||
- ${IDF_PATH}/make/build_examples.sh
|
||||
|
||||
build_docs:
|
||||
stage: build
|
||||
image: espressif/esp32-ci-env
|
||||
tags:
|
||||
- build_docs
|
||||
script:
|
||||
- cd docs
|
||||
- doxygen
|
||||
# If not building master branch, and there are Doxygen warnings, print them and bail out
|
||||
- test "${CI_BUILD_REF_NAME}" = "master" || test $(cat doxygen-warning-log.txt | wc -l) -eq 0 || ( echo "Doxygen pass had some warnings:" && cat doxygen-warning-log.txt && false )
|
||||
- make html
|
||||
artifacts:
|
||||
paths:
|
||||
- docs/_build/html
|
||||
expire_in: 1 mos
|
||||
|
||||
|
||||
test_nvs_on_host:
|
||||
stage: test
|
||||
image: espressif/esp32-ci-env
|
||||
tags:
|
||||
- nvs_host_test
|
||||
script:
|
||||
- cd components/nvs_flash/test
|
||||
- cd components/nvs_flash/test_nvs_host
|
||||
- make test
|
||||
|
||||
test_build_system:
|
||||
@@ -105,47 +147,33 @@ test_build_system:
|
||||
script:
|
||||
- ./make/test_build_system.sh
|
||||
|
||||
|
||||
|
||||
# template for test jobs
|
||||
.test_template: &test_template
|
||||
stage: test
|
||||
when: on_success
|
||||
test_report:
|
||||
stage: test_report
|
||||
only:
|
||||
- master
|
||||
- triggers
|
||||
|
||||
tags:
|
||||
- test_report
|
||||
variables:
|
||||
# need user to set SDK_NAME and CONFIG_FILE (may need to set BIN_PATH and APP_NAME later) in before_script
|
||||
SCRIPT_PATH: /home/gitlab-runner/auto_test_script
|
||||
BIN_PATH: ${CI_PROJECT_DIR}/SSC/build/
|
||||
APP_NAME: ssc
|
||||
LOG_PATH: $CI_PROJECT_DIR/$CI_BUILD_REF
|
||||
|
||||
LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF"
|
||||
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test"
|
||||
REPORT_PATH: "$CI_PROJECT_DIR/CI_Test_Report"
|
||||
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
|
||||
# clone test bench
|
||||
- git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git
|
||||
- cd auto_test_script
|
||||
# generate report
|
||||
- python CITestReport.py -l $LOG_PATH -t $TEST_CASE_FILE_PATH -p $REPORT_PATH
|
||||
|
||||
|
||||
push_master_to_github:
|
||||
before_script:
|
||||
before_script:
|
||||
- echo "Not setting up GitLab key, not fetching submodules"
|
||||
stage: deploy
|
||||
only:
|
||||
@@ -164,4 +192,279 @@ 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
|
||||
- git push --follow-tags github HEAD:master
|
||||
|
||||
|
||||
deploy_docs:
|
||||
before_script:
|
||||
- echo "Not setting up GitLab key, not fetching submodules"
|
||||
stage: deploy
|
||||
only:
|
||||
- master
|
||||
- triggers
|
||||
tags:
|
||||
- deploy
|
||||
image: espressif/esp32-ci-env
|
||||
script:
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 700 ~/.ssh
|
||||
- echo -n $DOCS_DEPLOY_KEY > ~/.ssh/id_rsa_base64
|
||||
- base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa
|
||||
- chmod 600 ~/.ssh/id_rsa
|
||||
- echo -e "Host $DOCS_SERVER\n\tStrictHostKeyChecking no\n\tUser $DOCS_SERVER_USER\n" >> ~/.ssh/config
|
||||
- export GIT_VER=$(git describe --always)
|
||||
- cd docs/_build/
|
||||
- mv html $GIT_VER
|
||||
- tar czvf $GIT_VER.tar.gz $GIT_VER
|
||||
- scp $GIT_VER.tar.gz $DOCS_SERVER:$DOCS_PATH
|
||||
- ssh $DOCS_SERVER -x "cd $DOCS_PATH && tar xzvf $GIT_VER.tar.gz && rm -f latest && ln -s $GIT_VER latest"
|
||||
|
||||
|
||||
# AUTO GENERATED PART START, DO NOT MODIFY CONTENT BELOW
|
||||
# template for test jobs
|
||||
.test_template: &test_template
|
||||
stage: test
|
||||
when: on_success
|
||||
only:
|
||||
- master
|
||||
- triggers
|
||||
allow_failure: true
|
||||
|
||||
variables:
|
||||
# LOCAL_ENV_CONFIG_PATH: define in template and jobs can overwrite if required
|
||||
LOCAL_ENV_CONFIG_PATH: /home/gitlab-runner/LocalConfig/ESP32_IDF
|
||||
BIN_PATH: "$CI_PROJECT_DIR/SSC/ssc_bin/SSC"
|
||||
APP_NAME: "ssc"
|
||||
LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF"
|
||||
# append test level folder to TEST_CASE_FILE_PATH in before_script of test job
|
||||
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test/integration_test"
|
||||
# jobs MUST set CONFIG_FILE in before_script, and overwrite the variables above if necessary
|
||||
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $LOG_PATH
|
||||
expire_in: 6 mos
|
||||
|
||||
script:
|
||||
# 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 test bench
|
||||
- git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git
|
||||
- cd auto_test_script
|
||||
# run test
|
||||
- python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH bin_path $APP_NAME $BIN_PATH
|
||||
|
||||
|
||||
# template for overnight test jobs
|
||||
.test_template_night: &test_template_night
|
||||
<<: *test_template
|
||||
only:
|
||||
# can only be triggered
|
||||
- triggers
|
||||
script:
|
||||
# must be night build triggers, otherwise exit without test
|
||||
- test $NIGHT_BUILD = "Yes" || exit 0
|
||||
# add gitlab ssh key
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 700 ~/.ssh
|
||||
- echo -n $GITLAB_KEY > ~/.ssh/id_rsa_base64
|
||||
- base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa
|
||||
- chmod 600 ~/.ssh/id_rsa
|
||||
- echo -e "Host gitlab.espressif.cn\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
|
||||
# clone test bench
|
||||
- git clone $GITLAB_SSH_SERVER/yinling/auto_test_script.git
|
||||
- cd auto_test_script
|
||||
# run test
|
||||
- python CIRunner.py -l $LOG_PATH -c $CONFIG_FILE -e $LOCAL_ENV_CONFIG_PATH -t $TEST_CASE_FILE_PATH bin_path $APP_NAME $BIN_PATH
|
||||
|
||||
# template for unit test jobs
|
||||
.unit_test_template: &unit_test_template
|
||||
<<: *test_template
|
||||
allow_failure: false
|
||||
stage: unit_test
|
||||
|
||||
variables:
|
||||
# jobs MUST set CONFIG_FILE in before_script, and overwrite the variables above if necessary
|
||||
LOCAL_ENV_CONFIG_PATH: /home/gitlab-runner/LocalConfig/ESP32_IDF
|
||||
BIN_PATH: "$CI_PROJECT_DIR/tools/unit-test-app/build/"
|
||||
LOG_PATH: "$CI_PROJECT_DIR/$CI_BUILD_REF"
|
||||
APP_NAME: "ut"
|
||||
TEST_CASE_FILE_PATH: "$CI_PROJECT_DIR/components/idf_test/unit_test"
|
||||
|
||||
UT_Function_SYS_01:
|
||||
<<: *unit_test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- UT_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/UT_Function_SYS_01.yml
|
||||
|
||||
IT_Function_SYS_01:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_SYS_01.yml
|
||||
|
||||
IT_Function_WIFI_01:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_01.yml
|
||||
|
||||
IT_Function_WIFI_02:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_02.yml
|
||||
|
||||
IT_Function_TCPIP_01:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_01.yml
|
||||
|
||||
IT_Function_TCPIP_02:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_02.yml
|
||||
|
||||
IT_Function_TCPIP_03:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_03.yml
|
||||
|
||||
IT_Function_TCPIP_04:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_04.yml
|
||||
|
||||
IT_Function_TCPIP_05:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_05.yml
|
||||
|
||||
IT_Function_TCPIP_06:
|
||||
<<: *test_template_night
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_06.yml
|
||||
|
||||
IT_Function_WIFI_03:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T3_PhyMode
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_03.yml
|
||||
|
||||
IT_Function_WIFI_04:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_APC
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_04.yml
|
||||
|
||||
IT_Function_WIFI_05:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_WEP
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_05.yml
|
||||
|
||||
IT_Function_WIFI_06:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T2_PhyMode
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_WIFI_06.yml
|
||||
|
||||
IT_Function_TCPIP_07:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T1_2
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_07.yml
|
||||
|
||||
IT_Function_TCPIP_08:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_08.yml
|
||||
|
||||
IT_Function_TCPIP_09:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_09.yml
|
||||
|
||||
IT_Function_TCPIP_10:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T1_2
|
||||
- SSC_T2_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_10.yml
|
||||
|
||||
IT_Function_TCPIP_11:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
- SSC_T1_2
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_11.yml
|
||||
|
||||
IT_Function_TCPIP_12:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32_IDF
|
||||
- SSC_T1_1
|
||||
before_script:
|
||||
- CONFIG_FILE=$TEST_CASE_FILE_PATH/CIConfigs/IT_Function_TCPIP_12.yml
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -7,3 +7,6 @@
|
||||
[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
|
||||
|
||||
@@ -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 the examples README <https://github.com/espressif/esp-idf/tree/master/examples>`_.
|
||||
|
||||
* Are comments and documentation written in clear English, with no spelling or grammar errors?
|
||||
|
||||
* If the contribution contains multiple commits, are they grouped together into logical changes (one major change per pull request)? Are any commits with names like "fixed typo" [squashed into previous commits](http://eli.thegreenplace.net/2014/02/19/squashing-github-pull-requests-into-a-single-commit/)?
|
||||
* If the contribution contains multiple commits, are they grouped together into logical changes (one major change per pull request)? Are any commits with names like "fixed typo" `squashed into previous commits <http://eli.thegreenplace.net/2014/02/19/squashing-github-pull-requests-into-a-single-commit/>`_?
|
||||
|
||||
* If you're unsure about any of these points, please open the Pull Request anyhow and then ask us for feedback.
|
||||
|
||||
## Pull Request Process
|
||||
Pull Request Process
|
||||
--------------------
|
||||
|
||||
After you open the Pull Request, there will probably be some discussion in the comments field of the request itself.
|
||||
|
||||
@@ -32,6 +38,10 @@ Once the Pull Request is ready to merge, it will first be merged into our intern
|
||||
|
||||
If this process passes, it will be merged onto the public github repository.
|
||||
|
||||
## Legal Part
|
||||
Legal Part
|
||||
----------
|
||||
|
||||
Before a contribution can be accepted, you will need to sign our :doc:`contributor-agreement`. You will be prompted for this automatically as part of the Pull Request process.
|
||||
|
||||
|
||||
|
||||
Before a contribution can be accepted, you will need to sign our [Contributor Agreement](docs/contributor-agreement.rst). You will be prompted for this automatically as part of the Pull Request process.
|
||||
20
Kconfig
20
Kconfig
@@ -23,6 +23,26 @@ endmenu
|
||||
|
||||
source "$COMPONENT_KCONFIGS_PROJBUILD"
|
||||
|
||||
choice OPTIMIZATION_LEVEL
|
||||
prompt "Optimization level"
|
||||
default OPTIMIZATION_LEVEL_DEBUG
|
||||
help
|
||||
This option sets optimization level.
|
||||
|
||||
- for "Release" setting, -Os flag is added to CFLAGS,
|
||||
and -DNDEBUG flag is added to CPPFLAGS.
|
||||
|
||||
- for "Debug" setting, -Og flag is added to CFLAGS.
|
||||
|
||||
To override any of these settings, set CFLAGS and/or CPPFLAGS
|
||||
in project makefile, before including $(IDF_PATH)/make/project.mk.
|
||||
|
||||
config OPTIMIZATION_LEVEL_DEBUG
|
||||
bool "Debug"
|
||||
config OPTIMIZATION_LEVEL_RELEASE
|
||||
bool "Release"
|
||||
endchoice
|
||||
|
||||
menu "Component config"
|
||||
source "$COMPONENT_KCONFIGS"
|
||||
endmenu
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Using Espressif IoT Development Framework with the ESP32
|
||||
|
||||
[](http://esp-idf.readthedocs.io/en/latest/?badge=latest)
|
||||
|
||||
# Setting Up ESP-IDF
|
||||
|
||||
In the [docs](docs) directory you will find per-platform setup guides:
|
||||
@@ -60,14 +62,15 @@ 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.
|
||||
|
||||
# Resources
|
||||
|
||||
* The [docs directory of the esp-idf repository](docs) contains esp-idf documentation.
|
||||
* The [docs directory of the esp-idf repository](docs) contains source of [esp-idf](http://esp-idf.readthedocs.io/) documentation.
|
||||
|
||||
* The [esp32.com forum](http://esp32.com/) is a place to ask questions and find community resources.
|
||||
|
||||
* [Check the Issues section on github](https://github.com/espressif/esp-idf/issues) if you find a bug or have a feature request. Please check existing Issues before opening a new one.
|
||||
|
||||
* If you're interested in contributing to esp-idf, please check the [CONTRIBUTING.md](CONTRIBUTING.md) file.
|
||||
* If you're interested in contributing to esp-idf, please check the [Contributions Guide](http://esp-idf.readthedocs.io/en/latest/contributing.html>).
|
||||
|
||||
|
||||
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.)
|
||||
|
||||
381
components/app_update/esp_ota_ops.c
Normal file
381
components/app_update/esp_ota_ops.c
Normal file
@@ -0,0 +1,381 @@
|
||||
// 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 "sdkconfig.h"
|
||||
|
||||
#include "esp_ota_ops.h"
|
||||
#include "rom/queue.h"
|
||||
#include "rom/crc.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
|
||||
#define OTA_MAX(a,b) ((a) >= (b) ? (a) : (b))
|
||||
#define OTA_MIN(a,b) ((a) <= (b) ? (a) : (b))
|
||||
#define SUB_TYPE_ID(i) (i & 0x0F)
|
||||
|
||||
typedef struct ota_ops_entry_ {
|
||||
uint32_t handle;
|
||||
esp_partition_t part;
|
||||
uint32_t erased_size;
|
||||
uint32_t wrote_size;
|
||||
LIST_ENTRY(ota_ops_entry_) entries;
|
||||
} ota_ops_entry_t;
|
||||
|
||||
/* OTA selection structure (two copies in the OTA data partition.)
|
||||
Size of 32 bytes is friendly to flash encryption */
|
||||
typedef struct {
|
||||
uint32_t ota_seq;
|
||||
uint8_t seq_label[24];
|
||||
uint32_t crc; /* CRC32 of ota_seq field only */
|
||||
} ota_select;
|
||||
|
||||
static LIST_HEAD(ota_ops_entries_head, ota_ops_entry_) s_ota_ops_entries_head =
|
||||
LIST_HEAD_INITIALIZER(s_ota_ops_entries_head);
|
||||
|
||||
static uint32_t s_ota_ops_last_handle = 0;
|
||||
static ota_select s_ota_select[2];
|
||||
|
||||
const static char *TAG = "esp_ota_ops";
|
||||
|
||||
esp_err_t esp_ota_begin(const esp_partition_t *partition, size_t image_size, esp_ota_handle_t *out_handle)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
|
||||
if ((partition == NULL) || (out_handle == NULL)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
ota_ops_entry_t *new_entry = (ota_ops_entry_t *) calloc(sizeof(ota_ops_entry_t), 1);
|
||||
|
||||
if (new_entry == 0) {
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
// if input image size is 0 or OTA_SIZE_UNKNOWN, will erase all areas in this partition
|
||||
if ((image_size == 0) || (image_size == OTA_SIZE_UNKNOWN)) {
|
||||
ret = esp_partition_erase_range(partition, 0, partition->size);
|
||||
} else {
|
||||
ret = esp_partition_erase_range(partition, 0, (image_size / SPI_FLASH_SEC_SIZE + 1) * SPI_FLASH_SEC_SIZE);
|
||||
}
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
free(new_entry);
|
||||
new_entry = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
LIST_INSERT_HEAD(&s_ota_ops_entries_head, new_entry, entries);
|
||||
|
||||
if ((image_size == 0) || (image_size == OTA_SIZE_UNKNOWN)) {
|
||||
new_entry->erased_size = partition->size;
|
||||
} else {
|
||||
new_entry->erased_size = image_size;
|
||||
}
|
||||
|
||||
memcpy(&new_entry->part, partition, sizeof(esp_partition_t));
|
||||
new_entry->handle = ++s_ota_ops_last_handle;
|
||||
*out_handle = new_entry->handle;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size)
|
||||
{
|
||||
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");
|
||||
ret = esp_partition_write(&it->part, it->wrote_size, data, 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)
|
||||
{
|
||||
esp_err_t ret;
|
||||
ota_ops_entry_t *it;
|
||||
size_t image_size;
|
||||
for (it = LIST_FIRST(&s_ota_ops_entries_head); it != NULL; it = LIST_NEXT(it, entries)) {
|
||||
if (it->handle == handle) {
|
||||
// an ota handle need to be ended after erased and wrote data in it
|
||||
if ((it->erased_size == 0) || (it->wrote_size == 0)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECUREBOOTLOADER
|
||||
if (esp_image_basic_verify(it->part.address, &image_size) != ESP_OK) {
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
ret = esp_secure_boot_verify_signature(it->part.address, image_size);
|
||||
if (ret != ESP_OK) {
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
#endif
|
||||
|
||||
LIST_REMOVE(it, entries);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (it == NULL) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
free(it);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static uint32_t ota_select_crc(const ota_select *s)
|
||||
{
|
||||
return crc32_le(UINT32_MAX, (uint8_t *)&s->ota_seq, 4);
|
||||
}
|
||||
|
||||
static bool ota_select_valid(const ota_select *s)
|
||||
{
|
||||
return s->ota_seq != UINT32_MAX && s->crc == ota_select_crc(s);
|
||||
}
|
||||
|
||||
static esp_err_t rewrite_ota_seq(uint32_t seq, uint8_t sec_id, const esp_partition_t *ota_data_partition)
|
||||
{
|
||||
esp_err_t ret;
|
||||
|
||||
if (sec_id == 0 || sec_id == 1) {
|
||||
s_ota_select[sec_id].ota_seq = seq;
|
||||
s_ota_select[sec_id].crc = ota_select_crc(&s_ota_select[sec_id]);
|
||||
ret = esp_partition_erase_range(ota_data_partition, sec_id * SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
} else {
|
||||
return esp_partition_write(ota_data_partition, SPI_FLASH_SEC_SIZE * sec_id, &s_ota_select[sec_id].ota_seq, sizeof(ota_select));
|
||||
}
|
||||
} else {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t get_ota_partition_count(void)
|
||||
{
|
||||
uint16_t ota_app_count = 0;
|
||||
while (esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ota_app_count, NULL) != NULL) {
|
||||
assert(ota_app_count < 16 && "must erase the partition before writing to it");
|
||||
ota_app_count++;
|
||||
}
|
||||
return ota_app_count;
|
||||
}
|
||||
|
||||
static esp_err_t esp_rewrite_ota_data(esp_partition_subtype_t subtype)
|
||||
{
|
||||
esp_err_t ret;
|
||||
const esp_partition_t *find_partition = NULL;
|
||||
uint16_t ota_app_count = 0;
|
||||
uint32_t i = 0;
|
||||
uint32_t seq;
|
||||
static spi_flash_mmap_memory_t ota_data_map;
|
||||
const void *result = NULL;
|
||||
|
||||
find_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
if (find_partition != NULL) {
|
||||
ota_app_count = get_ota_partition_count();
|
||||
//esp32_idf use two sector for store information about which partition is running
|
||||
//it defined the two sector as ota data partition,two structure ota_select is saved in the two sector
|
||||
//named data in first sector as s_ota_select[0], second sector data as s_ota_select[1]
|
||||
//e.g.
|
||||
//if s_ota_select[0].ota_seq == s_ota_select[1].ota_seq == 0xFFFFFFFF,means ota info partition is in init status
|
||||
//so it will boot factory application(if there is),if there's no factory application,it will boot ota[0] application
|
||||
//if s_ota_select[0].ota_seq != 0 and s_ota_select[1].ota_seq != 0,it will choose a max seq ,and get value of max_seq%max_ota_app_number
|
||||
//and boot a subtype (mask 0x0F) value is (max_seq - 1)%max_ota_app_number,so if want switch to run ota[x],can use next formulas.
|
||||
//for example, if s_ota_select[0].ota_seq = 4, s_ota_select[1].ota_seq = 5, and there are 8 ota application,
|
||||
//current running is (5-1)%8 = 4,running ota[4],so if we want to switch to run ota[7],
|
||||
//we should add s_ota_select[0].ota_seq (is 4) to 4 ,(8-1)%8=7,then it will boot ota[7]
|
||||
//if A=(B - C)%D
|
||||
//then B=(A + C)%D + D*n ,n= (0,1,2...)
|
||||
//so current ota app sub type id is x , dest bin subtype is y,total ota app count is n
|
||||
//seq will add (x + n*1 + 1 - seq)%n
|
||||
if (SUB_TYPE_ID(subtype) >= ota_app_count) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
ret = esp_partition_mmap(find_partition, 0, find_partition->size, SPI_FLASH_MMAP_DATA, &result, &ota_data_map);
|
||||
if (ret != ESP_OK) {
|
||||
result = NULL;
|
||||
return ret;
|
||||
} else {
|
||||
memcpy(&s_ota_select[0], result, sizeof(ota_select));
|
||||
memcpy(&s_ota_select[1], result + SPI_FLASH_SEC_SIZE, sizeof(ota_select));
|
||||
spi_flash_munmap(ota_data_map);
|
||||
}
|
||||
|
||||
if (ota_select_valid(&s_ota_select[0]) && ota_select_valid(&s_ota_select[1])) {
|
||||
seq = OTA_MAX(s_ota_select[0].ota_seq, s_ota_select[1].ota_seq);
|
||||
while (seq > (SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count) {
|
||||
i++;
|
||||
}
|
||||
|
||||
if (s_ota_select[0].ota_seq >= s_ota_select[1].ota_seq) {
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 0, find_partition);
|
||||
} else {
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 1, find_partition);
|
||||
}
|
||||
|
||||
} else if (ota_select_valid(&s_ota_select[0])) {
|
||||
while (s_ota_select[0].ota_seq > (SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count) {
|
||||
i++;
|
||||
}
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 1, find_partition);
|
||||
|
||||
} else if (ota_select_valid(&s_ota_select[1])) {
|
||||
while (s_ota_select[1].ota_seq > (SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count) {
|
||||
i++;
|
||||
}
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 0, find_partition);
|
||||
|
||||
} else if (s_ota_select[0].ota_seq == 0xFFFFFFFF && s_ota_select[1].ota_seq == 0xFFFFFFFF) {
|
||||
return rewrite_ota_seq(SUB_TYPE_ID(subtype) + 1, 0, find_partition);
|
||||
|
||||
} else {
|
||||
return ESP_ERR_OTA_SELECT_INFO_INVALID;
|
||||
}
|
||||
|
||||
} else {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_set_boot_partition(const esp_partition_t *partition)
|
||||
{
|
||||
const esp_partition_t *find_partition = NULL;
|
||||
size_t image_size;
|
||||
if (partition == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECUREBOOTLOADER
|
||||
if (esp_image_basic_verify(partition->address, &image_size) != ESP_OK) {
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
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 bin 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 bin......");
|
||||
|
||||
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 bin......", \
|
||||
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 bin......", \
|
||||
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 bin......", \
|
||||
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, "not found current bin");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
110
components/app_update/include/esp_ota_ops.h
Executable file
110
components/app_update/include/esp_ota_ops.h
Executable file
@@ -0,0 +1,110 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _OTA_OPS_H
|
||||
#define _OTA_OPS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_partition.h"
|
||||
#include "esp_spi_flash.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#define OTA_SIZE_UNKNOWN 0xffffffff
|
||||
|
||||
#define ESP_ERR_OTA_BASE 0x1500 /*!< base error code for ota_ops api */
|
||||
#define ESP_ERR_OTA_PARTITION_CONFLICT (ESP_ERR_OTA_BASE + 0x01) /*!< want to write or erase current running partition */
|
||||
#define ESP_ERR_OTA_SELECT_INFO_INVALID (ESP_ERR_OTA_BASE + 0x02) /*!< ota data partition info is error */
|
||||
#define ESP_ERR_OTA_VALIDATE_FAILED (ESP_ERR_OTA_BASE + 0x03) /*!< validate ota image failed */
|
||||
|
||||
/**
|
||||
* @brief Opaque handle for application update obtained from app_ops.
|
||||
*/
|
||||
typedef uint32_t esp_ota_handle_t;
|
||||
|
||||
/**
|
||||
* @brief format input partition in flash to 0xFF as input image size,
|
||||
* if unkown image size ,pass 0x0 or 0xFFFFFFFF, it will erase all the
|
||||
* partition ,Otherwise, erase the required range
|
||||
*
|
||||
* @param partition Pointer to partition structure which need to be updated
|
||||
* Must be non-NULL.
|
||||
* @param image_size size of image need to be updated
|
||||
* @param out_handle handle which should be used for esp_ota_write or esp_ota_end call
|
||||
|
||||
* @return:
|
||||
* - ESP_OK: if format ota image OK
|
||||
* - ESP_ERR_OTA_PARTITION_CONFLICT: operate current running bin
|
||||
* - ESP_ERR_OTA_SELECT_INFO_INVALID: ota bin select info invalid
|
||||
*/
|
||||
esp_err_t esp_ota_begin(const esp_partition_t* partition, size_t image_size, esp_ota_handle_t* out_handle);
|
||||
|
||||
/**
|
||||
* @brief Write data to input input partition
|
||||
*
|
||||
* @param handle Handle obtained from esp_ota_begin
|
||||
* @param data Pointer to data write to flash
|
||||
* @param size data size of recieved data
|
||||
*
|
||||
* @return:
|
||||
* - ESP_OK: if write flash data OK
|
||||
* - ESP_ERR_OTA_PARTITION_CONFLICT: operate current running bin
|
||||
* - ESP_ERR_OTA_SELECT_INFO_INVALID: ota bin select info invalid
|
||||
*/
|
||||
esp_err_t esp_ota_write(esp_ota_handle_t handle, const void* data, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Finish the update and validate written data
|
||||
*
|
||||
* @param handle Handle obtained from esp_ota_begin
|
||||
*
|
||||
* @return:
|
||||
* - ESP_OK: if validate ota image pass
|
||||
* - ESP_ERR_OTA_VALIDATE_FAILED: validate the ota image is invalid
|
||||
*/
|
||||
esp_err_t esp_ota_end(esp_ota_handle_t handle);
|
||||
|
||||
/**
|
||||
* @brief Set next boot partition, call system_restart() will switch to run it
|
||||
*
|
||||
* @note if you want switch to run a bin file
|
||||
* has never been checked before,please validate it's signature firstly
|
||||
*
|
||||
* @param partition Pointer to partition structure which need to boot
|
||||
*
|
||||
* @return:
|
||||
* - ESP_OK: if set next boot partition OK
|
||||
* - ESP_ERR_OTA_SELECT_INFO_INVALID: ota bin select info invalid
|
||||
*/
|
||||
esp_err_t esp_ota_set_boot_partition(const esp_partition_t* partition);
|
||||
|
||||
/**
|
||||
* @brief Get partition info of current running image
|
||||
*
|
||||
* @return pointer to esp_partition_t structure, or NULL if no partition is found or
|
||||
* operate flash failed,This pointer is valid for the lifetime of the application.
|
||||
*/
|
||||
const esp_partition_t* esp_ota_get_boot_partition(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* OTA_OPS_H */
|
||||
@@ -20,12 +20,99 @@ config LOG_BOOTLOADER_LEVEL_VERBOSE
|
||||
endchoice
|
||||
|
||||
config LOG_BOOTLOADER_LEVEL
|
||||
int
|
||||
default 0 if LOG_BOOTLOADER_LEVEL_NONE
|
||||
default 1 if LOG_BOOTLOADER_LEVEL_ERROR
|
||||
default 2 if LOG_BOOTLOADER_LEVEL_WARN
|
||||
default 3 if LOG_BOOTLOADER_LEVEL_INFO
|
||||
default 4 if LOG_BOOTLOADER_LEVEL_DEBUG
|
||||
default 5 if LOG_BOOTLOADER_LEVEL_VERBOSE
|
||||
int
|
||||
default 0 if LOG_BOOTLOADER_LEVEL_NONE
|
||||
default 1 if LOG_BOOTLOADER_LEVEL_ERROR
|
||||
default 2 if LOG_BOOTLOADER_LEVEL_WARN
|
||||
default 3 if LOG_BOOTLOADER_LEVEL_INFO
|
||||
default 4 if LOG_BOOTLOADER_LEVEL_DEBUG
|
||||
default 5 if LOG_BOOTLOADER_LEVEL_VERBOSE
|
||||
|
||||
endmenu
|
||||
|
||||
|
||||
|
||||
menu "Secure boot configuration"
|
||||
|
||||
choice SECURE_BOOTLOADER
|
||||
bool "Secure bootloader"
|
||||
default SECURE_BOOTLOADER_DISABLED
|
||||
help
|
||||
Build a bootloader with the secure boot flag enabled.
|
||||
|
||||
Secure bootloader can be one-time-flash (chip will only ever
|
||||
boot that particular bootloader), or a digest key can be used
|
||||
to allow the secure bootloader to be re-flashed with
|
||||
modifications. Secure boot also permanently disables JTAG.
|
||||
|
||||
See docs/security/secure-boot.rst for details.
|
||||
|
||||
config SECURE_BOOTLOADER_DISABLED
|
||||
bool "Disabled"
|
||||
|
||||
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_SIGNING_KEY
|
||||
string "Secure boot signing key"
|
||||
depends on SECURE_BOOTLOADER_ENABLED
|
||||
default secure_boot_signing_key.pem
|
||||
help
|
||||
Path to the key file used to sign partition tables and app images for secure boot.
|
||||
|
||||
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_DISABLE_JTAG
|
||||
bool "First boot: Permanently disable JTAG"
|
||||
depends on SECURE_BOOTLOADER_ENABLED
|
||||
default Y
|
||||
help
|
||||
Bootloader permanently disable JTAG (across entire chip) when enabling secure boot. This happens on first boot of the bootloader.
|
||||
|
||||
It is recommended this option remains set for production environments.
|
||||
|
||||
config SECURE_BOOT_DISABLE_ROM_BASIC
|
||||
bool "First boot: Permanently disable ROM BASIC fallback"
|
||||
depends on SECURE_BOOTLOADER_ENABLED
|
||||
default Y
|
||||
help
|
||||
Bootloader permanently disables ROM BASIC (on UART console) as a fallback if the bootloader image becomes invalid. This happens on first boot.
|
||||
|
||||
It is recommended this option remains set in production environments.
|
||||
|
||||
config SECURE_BOOT_TEST_MODE
|
||||
bool "Test mode: don't actually enable secure boot"
|
||||
depends on SECURE_BOOTLOADER_ENABLED
|
||||
default N
|
||||
help
|
||||
If this option is set, all permanent secure boot changes (via Efuse) are disabled.
|
||||
|
||||
This option is for testing purposes only - it effectively completely disables secure boot protection.
|
||||
|
||||
config SECURE_BOOTLOADER_ENABLED
|
||||
bool
|
||||
default SECURE_BOOTLOADER_ONE_TIME_FLASH || SECURE_BOOTLOADER_REFLASHABLE
|
||||
|
||||
endmenu
|
||||
@@ -8,44 +8,115 @@
|
||||
# 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
|
||||
|
||||
# Custom recursive make for bootloader sub-project
|
||||
BOOTLOADER_MAKE=+$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src \
|
||||
V=$(V) BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) TEST_COMPONENTS=
|
||||
|
||||
.PHONY: bootloader-clean bootloader-flash bootloader $(BOOTLOADER_BIN)
|
||||
|
||||
$(BOOTLOADER_BIN): $(COMPONENT_PATH)/src/sdkconfig
|
||||
$(Q) PROJECT_PATH= \
|
||||
BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \
|
||||
$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src MAKEFLAGS= V=$(V) TARGET_BIN_LAYOUT="$(BOOTLOADER_TARGET_BIN_LAYOUT)" $(BOOTLOADER_BIN)
|
||||
|
||||
bootloader-clean:
|
||||
$(Q) PROJECT_PATH= \
|
||||
BUILD_DIR_BASE=$(BOOTLOADER_BUILD_DIR) \
|
||||
$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src app-clean MAKEFLAGS= V=$(V)
|
||||
$(BOOTLOADER_BIN): $(SDKCONFIG_MAKEFILE)
|
||||
$(BOOTLOADER_MAKE) $@
|
||||
|
||||
clean: bootloader-clean
|
||||
|
||||
bootloader: $(BOOTLOADER_BIN)
|
||||
@echo "Bootloader built. Default flash command is:"
|
||||
@echo "$(ESPTOOLPY_WRITE_FLASH) 0x1000 $(BOOTLOADER_BIN)"
|
||||
ifdef CONFIG_SECURE_BOOTLOADER_DISABLED
|
||||
# If secure boot disabled, bootloader flashing is integrated
|
||||
# with 'make flash' and no warnings are printed.
|
||||
|
||||
all_binaries: $(BOOTLOADER_BIN)
|
||||
bootloader: $(BOOTLOADER_BIN)
|
||||
@echo $(SEPARATOR)
|
||||
@echo "Bootloader built. Default flash command is:"
|
||||
@echo "$(ESPTOOLPY_WRITE_FLASH) 0x1000 $^"
|
||||
|
||||
ESPTOOL_ALL_FLASH_ARGS += 0x1000 $(BOOTLOADER_BIN)
|
||||
|
||||
# synchronise the project level config to the component's
|
||||
# config
|
||||
$(COMPONENT_PATH)/src/sdkconfig: $(PROJECT_PATH)/sdkconfig
|
||||
$(Q) cp $< $@
|
||||
|
||||
# bootloader-flash calls flash in the bootloader dummy project
|
||||
bootloader-flash: $(BOOTLOADER_BIN)
|
||||
$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src flash MAKEFLAGS= V=$(V)
|
||||
$(ESPTOOLPY_WRITE_FLASH) 0x1000 $^
|
||||
|
||||
else ifdef CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH
|
||||
|
||||
#### TEMPORARILY DISABLE THIS OPTION
|
||||
ifneq ("$(IDF_INSECURE_SECURE_BOOT)","1")
|
||||
bootloader:
|
||||
@echo "Secure boot features are not yet mature, so the current secure bootloader will not properly secure the device"
|
||||
@echo "If you flash this bootloader, you will be left with an non-updateable bootloader that is missing features."
|
||||
@echo "If you really want to do this, set the environment variable IDF_INSECURE_SECURE_BOOT=1 and rerun make."
|
||||
exit 1
|
||||
else
|
||||
|
||||
# One time flashing requires user to run esptool.py command themselves,
|
||||
# and warning is printed about inability to reflash.
|
||||
|
||||
bootloader: $(BOOTLOADER_BIN)
|
||||
@echo $(SEPARATOR)
|
||||
@echo "Bootloader built. One-time flash command is:"
|
||||
@echo "$(ESPTOOLPY_WRITE_FLASH) 0x1000 $(BOOTLOADER_BIN)"
|
||||
@echo $(SEPARATOR)
|
||||
@echo "* IMPORTANT: After first boot, BOOTLOADER CANNOT BE RE-FLASHED on same device"
|
||||
|
||||
endif # IDF_INSECURE_SECURE_BOOT
|
||||
else ifdef CONFIG_SECURE_BOOTLOADER_REFLASHABLE
|
||||
# Reflashable secure bootloader
|
||||
# generates a digest binary (bootloader + digest)
|
||||
|
||||
#### TEMPORARILY DISABLE THIS OPTION
|
||||
ifneq ("$(IDF_INSECURE_SECURE_BOOT)","1")
|
||||
bootloader:
|
||||
@echo "Secure boot features are not yet mature, so the current secure bootloader will not properly secure the device."
|
||||
@echo "If using this feature, expect to reflash the bootloader at least one more time."
|
||||
@echo "If you really want to do this, set the environment variable IDF_INSECURE_SECURE_BOOT=1 and rerun make."
|
||||
exit 1
|
||||
else
|
||||
|
||||
BOOTLOADER_DIGEST_BIN := $(BOOTLOADER_BUILD_DIR)/bootloader-reflash-digest.bin
|
||||
SECURE_BOOTLOADER_KEY := $(BOOTLOADER_BUILD_DIR)/secure-bootloader-key.bin
|
||||
|
||||
$(SECURE_BOOTLOADER_KEY): $(SECURE_BOOT_SIGNING_KEY)
|
||||
$(Q) $(ESPSECUREPY) digest_private_key -k $< $@
|
||||
|
||||
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) 0x1000 $(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 $@ $<
|
||||
|
||||
endif # IDF_INSECURE_SECURE_BOOT
|
||||
else
|
||||
bootloader:
|
||||
@echo "Invalid bootloader target: bad sdkconfig?"
|
||||
@exit 1
|
||||
endif
|
||||
|
||||
all_binaries: $(BOOTLOADER_BIN)
|
||||
|
||||
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
|
||||
CFLAGS += -D BOOTLOADER_BUILD=1 -I $(IDF_PATH)/components/esp32/include
|
||||
|
||||
endif
|
||||
|
||||
@@ -4,14 +4,18 @@
|
||||
#
|
||||
|
||||
PROJECT_NAME := bootloader
|
||||
COMPONENTS := esptool_py bootloader log
|
||||
|
||||
#We cannot include the esp32 component directly but we need its includes.
|
||||
#This is fixed by adding CFLAGS from Makefile.projbuild
|
||||
COMPONENTS := esptool_py bootloader bootloader_support log spi_flash micro-ecc
|
||||
|
||||
# The bootloader pseudo-component is also included in this build, for its Kconfig.projbuild to be included.
|
||||
#
|
||||
# IS_BOOTLOADER_BUILD tells the component Makefile.projbuild to be a no-op
|
||||
IS_BOOTLOADER_BUILD := 1
|
||||
export IS_BOOTLOADER_BUILD
|
||||
|
||||
#We cannot include the esp32 component directly but we need its includes.
|
||||
#This is fixed by adding CFLAGS from Makefile.projbuild
|
||||
# include the top-level "project" include directory, for sdkconfig.h
|
||||
CFLAGS += -I$(BUILD_DIR_BASE)/../include
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
|
||||
@@ -20,12 +20,11 @@
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "esp_flash_data_types.h"
|
||||
|
||||
#define BOOT_VERSION "V0.1"
|
||||
#define SPI_SEC_SIZE 0x1000
|
||||
#define MEM_CACHE(offset) (uint8_t *)(0x3f400000 + (offset))
|
||||
#define CACHE_READ_32(offset) ((uint32_t *)(0x3f400000 + (offset)))
|
||||
#define PARTITION_ADD 0x4000
|
||||
#define PARTITION_MAGIC 0x50AA
|
||||
#define IROM_LOW 0x400D0000
|
||||
#define IROM_HIGH 0x40400000
|
||||
#define DROM_LOW 0x3F400000
|
||||
@@ -35,74 +34,6 @@ extern "C"
|
||||
#define RTC_DATA_LOW 0x50000000
|
||||
#define RTC_DATA_HIGH 0x50002000
|
||||
|
||||
/*spi mode,saved in third byte in flash */
|
||||
enum {
|
||||
SPI_MODE_QIO,
|
||||
SPI_MODE_QOUT,
|
||||
SPI_MODE_DIO,
|
||||
SPI_MODE_DOUT,
|
||||
SPI_MODE_FAST_READ,
|
||||
SPI_MODE_SLOW_READ
|
||||
};
|
||||
/* spi speed*/
|
||||
enum {
|
||||
SPI_SPEED_40M,
|
||||
SPI_SPEED_26M,
|
||||
SPI_SPEED_20M,
|
||||
SPI_SPEED_80M = 0xF
|
||||
};
|
||||
/*suppport flash size in esp32 */
|
||||
enum {
|
||||
SPI_SIZE_1MB = 0,
|
||||
SPI_SIZE_2MB,
|
||||
SPI_SIZE_4MB,
|
||||
SPI_SIZE_8MB,
|
||||
SPI_SIZE_16MB,
|
||||
SPI_SIZE_MAX
|
||||
};
|
||||
|
||||
|
||||
struct flash_hdr {
|
||||
char magic;
|
||||
char blocks;
|
||||
char spi_mode; /* flag of flash read mode in unpackage and usage in future */
|
||||
char spi_speed: 4; /* low bit */
|
||||
char spi_size: 4;
|
||||
unsigned int entry_addr;
|
||||
uint8_t encrypt_flag; /* encrypt flag */
|
||||
uint8_t secury_boot_flag; /* secury boot flag */
|
||||
char extra_header[14]; /* ESP32 additional header, unused by second bootloader */
|
||||
};
|
||||
|
||||
/* each header of flash bin block */
|
||||
struct block_hdr {
|
||||
unsigned int load_addr;
|
||||
unsigned int data_len;
|
||||
};
|
||||
|
||||
/* OTA selection structure (two copies in the OTA data partition.)
|
||||
|
||||
Size of 32 bytes is friendly to flash encryption */
|
||||
typedef struct {
|
||||
uint32_t ota_seq;
|
||||
uint8_t seq_label[24];
|
||||
uint32_t crc; /* CRC32 of ota_seq field only */
|
||||
} ota_select;
|
||||
|
||||
typedef struct {
|
||||
uint32_t offset;
|
||||
uint32_t size;
|
||||
} partition_pos_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t magic;
|
||||
uint8_t type; /* partition Type */
|
||||
uint8_t subtype; /* part_subtype */
|
||||
partition_pos_t pos;
|
||||
uint8_t label[16]; /* label for the partition */
|
||||
uint8_t reserved[4]; /* reserved */
|
||||
} partition_info_t;
|
||||
|
||||
#define PART_TYPE_APP 0x00
|
||||
#define PART_SUBTYPE_FACTORY 0x00
|
||||
#define PART_SUBTYPE_OTA_FLAG 0x10
|
||||
@@ -120,20 +51,15 @@ typedef struct {
|
||||
#define SPI_ERROR_LOG "spi flash error"
|
||||
|
||||
typedef struct {
|
||||
partition_pos_t ota_info;
|
||||
partition_pos_t factory;
|
||||
partition_pos_t test;
|
||||
partition_pos_t ota[16];
|
||||
esp_partition_pos_t ota_info;
|
||||
esp_partition_pos_t factory;
|
||||
esp_partition_pos_t test;
|
||||
esp_partition_pos_t ota[16];
|
||||
uint32_t app_count;
|
||||
uint32_t selected_subtype;
|
||||
} bootloader_state_t;
|
||||
|
||||
void boot_cache_redirect( uint32_t pos, size_t size );
|
||||
uint32_t get_bin_len(uint32_t pos);
|
||||
|
||||
bool flash_encrypt(bootloader_state_t *bs);
|
||||
bool secure_boot(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
@@ -33,6 +33,9 @@
|
||||
#include "soc/timer_group_reg.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_secure_boot.h"
|
||||
#include "bootloader_flash.h"
|
||||
|
||||
#include "bootloader_config.h"
|
||||
|
||||
@@ -49,15 +52,16 @@ flash cache is down and the app CPU is in reset. We do have a stack, so we can d
|
||||
extern void Cache_Flush(int);
|
||||
|
||||
void bootloader_main();
|
||||
void unpack_load_app(const partition_pos_t *app_node);
|
||||
void print_flash_info(struct flash_hdr* pfhdr);
|
||||
void IRAM_ATTR set_cache_and_start_app(uint32_t drom_addr,
|
||||
static void unpack_load_app(const esp_partition_pos_t *app_node);
|
||||
void print_flash_info(const esp_image_header_t* pfhdr);
|
||||
void set_cache_and_start_app(uint32_t drom_addr,
|
||||
uint32_t drom_load_addr,
|
||||
uint32_t drom_size,
|
||||
uint32_t irom_addr,
|
||||
uint32_t irom_load_addr,
|
||||
uint32_t irom_size,
|
||||
uint32_t entry_addr);
|
||||
static void update_flash_config(const esp_image_header_t* pfhdr);
|
||||
|
||||
|
||||
void IRAM_ATTR call_start_cpu0()
|
||||
@@ -93,53 +97,6 @@ void IRAM_ATTR call_start_cpu0()
|
||||
bootloader_main();
|
||||
}
|
||||
|
||||
/**
|
||||
* @function : get_bin_len
|
||||
* @description: get bin's length
|
||||
*
|
||||
* @inputs: pos bin locate address in flash
|
||||
* @return: uint32 length of bin,if bin MAGIC error return 0
|
||||
*/
|
||||
|
||||
uint32_t get_bin_len(uint32_t pos)
|
||||
{
|
||||
uint32_t len = 8 + 16;
|
||||
uint8_t i;
|
||||
ESP_LOGD(TAG, "pos %d %x",pos,*(uint8_t *)pos);
|
||||
if(0xE9 != *(uint8_t *)pos) {
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < *(uint8_t *)(pos + 1); i++) {
|
||||
len += *(uint32_t *)(pos + len + 4) + 8;
|
||||
}
|
||||
if (len % 16 != 0) {
|
||||
len = (len / 16 + 1) * 16;
|
||||
} else {
|
||||
len += 16;
|
||||
}
|
||||
ESP_LOGD(TAG, "bin length = %d", len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* @function : boot_cache_redirect
|
||||
* @description: Configure several pages in flash map so that `size` bytes
|
||||
* starting at `pos` are mapped to 0x3f400000.
|
||||
* This sets up mapping only for PRO CPU.
|
||||
*
|
||||
* @inputs: pos address in flash
|
||||
* size size of the area to map, in bytes
|
||||
*/
|
||||
void boot_cache_redirect( uint32_t pos, size_t size )
|
||||
{
|
||||
uint32_t pos_aligned = pos & 0xffff0000;
|
||||
uint32_t count = (size + 0xffff) / 0x10000;
|
||||
Cache_Read_Disable( 0 );
|
||||
Cache_Flush( 0 );
|
||||
ESP_LOGD(TAG, "mmu set paddr=%08x count=%d", pos_aligned, count );
|
||||
cache_flash_mmu_set( 0, 0, 0x3f400000, pos_aligned, 64, count );
|
||||
Cache_Read_Enable( 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @function : load_partition_table
|
||||
@@ -147,95 +104,113 @@ void boot_cache_redirect( uint32_t pos, size_t size )
|
||||
* OTA info sector, factory app sector, and test app sector.
|
||||
*
|
||||
* @inputs: bs bootloader state structure used to save the data
|
||||
* addr address of partition table in flash
|
||||
* @return: return true, if the partition table is loaded (and MD5 checksum is valid)
|
||||
*
|
||||
*/
|
||||
bool load_partition_table(bootloader_state_t* bs, uint32_t addr)
|
||||
bool load_partition_table(bootloader_state_t* bs)
|
||||
{
|
||||
partition_info_t partition;
|
||||
uint32_t end = addr + 0x1000;
|
||||
int index = 0;
|
||||
const esp_partition_info_t *partitions;
|
||||
const int ESP_PARTITION_TABLE_DATA_LEN = 0xC00; /* length of actual data (signature is appended to this) */
|
||||
const int MAX_PARTITIONS = ESP_PARTITION_TABLE_DATA_LEN / sizeof(esp_partition_info_t);
|
||||
char *partition_usage;
|
||||
|
||||
ESP_LOGI(TAG, "Partition Table:");
|
||||
ESP_LOGI(TAG, "## Label Usage Type ST Offset Length");
|
||||
|
||||
while (addr < end) {
|
||||
ESP_LOGD(TAG, "load partition table entry from %x(%08x)", addr, MEM_CACHE(addr));
|
||||
memcpy(&partition, MEM_CACHE(addr), sizeof(partition));
|
||||
ESP_LOGD(TAG, "type=%x subtype=%x", partition.type, partition.subtype);
|
||||
#ifdef CONFIG_SECURE_BOOTLOADER_ENABLED
|
||||
if(esp_secure_boot_enabled()) {
|
||||
ESP_LOGI(TAG, "Verifying partition table signature...");
|
||||
esp_err_t err = esp_secure_boot_verify_signature(ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_DATA_LEN);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to verify partition table signature.");
|
||||
return false;
|
||||
}
|
||||
ESP_LOGD(TAG, "Partition table signature verified");
|
||||
}
|
||||
#endif
|
||||
|
||||
partitions = bootloader_mmap(ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_DATA_LEN);
|
||||
if (!partitions) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", ESP_PARTITION_TABLE_ADDR, ESP_PARTITION_TABLE_DATA_LEN);
|
||||
return false;
|
||||
}
|
||||
ESP_LOGD(TAG, "mapped partition table 0x%x at 0x%x", ESP_PARTITION_TABLE_ADDR, (intptr_t)partitions);
|
||||
|
||||
for(int i = 0; i < MAX_PARTITIONS; i++) {
|
||||
const esp_partition_info_t *partition = &partitions[i];
|
||||
ESP_LOGD(TAG, "load partition table entry 0x%x", (intptr_t)partition);
|
||||
ESP_LOGD(TAG, "type=%x subtype=%x", partition->type, partition->subtype);
|
||||
partition_usage = "unknown";
|
||||
|
||||
if (partition.magic == PARTITION_MAGIC) { /* valid partition definition */
|
||||
switch(partition.type) {
|
||||
case PART_TYPE_APP: /* app partition */
|
||||
switch(partition.subtype) {
|
||||
case PART_SUBTYPE_FACTORY: /* factory binary */
|
||||
bs->factory = partition.pos;
|
||||
partition_usage = "factory app";
|
||||
break;
|
||||
case PART_SUBTYPE_TEST: /* test binary */
|
||||
bs->test = partition.pos;
|
||||
partition_usage = "test app";
|
||||
break;
|
||||
default:
|
||||
/* OTA binary */
|
||||
if ((partition.subtype & ~PART_SUBTYPE_OTA_MASK) == PART_SUBTYPE_OTA_FLAG) {
|
||||
bs->ota[partition.subtype & PART_SUBTYPE_OTA_MASK] = partition.pos;
|
||||
++bs->app_count;
|
||||
partition_usage = "OTA app";
|
||||
}
|
||||
else {
|
||||
partition_usage = "Unknown app";
|
||||
}
|
||||
break;
|
||||
if (partition->magic != ESP_PARTITION_MAGIC) {
|
||||
/* invalid partition definition indicates end-of-table */
|
||||
break;
|
||||
}
|
||||
|
||||
/* valid partition table */
|
||||
switch(partition->type) {
|
||||
case PART_TYPE_APP: /* app partition */
|
||||
switch(partition->subtype) {
|
||||
case PART_SUBTYPE_FACTORY: /* factory binary */
|
||||
bs->factory = partition->pos;
|
||||
partition_usage = "factory app";
|
||||
break;
|
||||
case PART_SUBTYPE_TEST: /* test binary */
|
||||
bs->test = partition->pos;
|
||||
partition_usage = "test app";
|
||||
break;
|
||||
default:
|
||||
/* OTA binary */
|
||||
if ((partition->subtype & ~PART_SUBTYPE_OTA_MASK) == PART_SUBTYPE_OTA_FLAG) {
|
||||
bs->ota[partition->subtype & PART_SUBTYPE_OTA_MASK] = partition->pos;
|
||||
++bs->app_count;
|
||||
partition_usage = "OTA app";
|
||||
}
|
||||
break; /* PART_TYPE_APP */
|
||||
case PART_TYPE_DATA: /* data partition */
|
||||
switch(partition.subtype) {
|
||||
case PART_SUBTYPE_DATA_OTA: /* ota data */
|
||||
bs->ota_info = partition.pos;
|
||||
partition_usage = "OTA data";
|
||||
break;
|
||||
case PART_SUBTYPE_DATA_RF:
|
||||
partition_usage = "RF data";
|
||||
break;
|
||||
case PART_SUBTYPE_DATA_WIFI:
|
||||
partition_usage = "WiFi data";
|
||||
break;
|
||||
default:
|
||||
partition_usage = "Unknown data";
|
||||
break;
|
||||
else {
|
||||
partition_usage = "Unknown app";
|
||||
}
|
||||
break; /* PARTITION_USAGE_DATA */
|
||||
default: /* other partition type */
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* invalid partition magic number */
|
||||
else {
|
||||
break; /* todo: validate md5 */
|
||||
break; /* PART_TYPE_APP */
|
||||
case PART_TYPE_DATA: /* data partition */
|
||||
switch(partition->subtype) {
|
||||
case PART_SUBTYPE_DATA_OTA: /* ota data */
|
||||
bs->ota_info = partition->pos;
|
||||
partition_usage = "OTA data";
|
||||
break;
|
||||
case PART_SUBTYPE_DATA_RF:
|
||||
partition_usage = "RF data";
|
||||
break;
|
||||
case PART_SUBTYPE_DATA_WIFI:
|
||||
partition_usage = "WiFi data";
|
||||
break;
|
||||
default:
|
||||
partition_usage = "Unknown data";
|
||||
break;
|
||||
}
|
||||
break; /* PARTITION_USAGE_DATA */
|
||||
default: /* other partition type */
|
||||
break;
|
||||
}
|
||||
|
||||
/* print partition type info */
|
||||
ESP_LOGI(TAG, "%2d %-16s %-16s %02x %02x %08x %08x", index, partition.label, partition_usage,
|
||||
partition.type, partition.subtype,
|
||||
partition.pos.offset, partition.pos.size);
|
||||
index++;
|
||||
addr += sizeof(partition);
|
||||
ESP_LOGI(TAG, "%2d %-16s %-16s %02x %02x %08x %08x", i, partition->label, partition_usage,
|
||||
partition->type, partition->subtype,
|
||||
partition->pos.offset, partition->pos.size);
|
||||
}
|
||||
|
||||
bootloader_munmap(partitions);
|
||||
|
||||
ESP_LOGI(TAG,"End of partition table");
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint32_t ota_select_crc(const ota_select *s)
|
||||
static uint32_t ota_select_crc(const esp_ota_select_entry_t *s)
|
||||
{
|
||||
return crc32_le(UINT32_MAX, (uint8_t*)&s->ota_seq, 4);
|
||||
}
|
||||
|
||||
static bool ota_select_valid(const ota_select *s)
|
||||
static bool ota_select_valid(const esp_ota_select_entry_t *s)
|
||||
{
|
||||
return s->ota_seq != UINT32_MAX && s->crc == ota_select_crc(s);
|
||||
}
|
||||
@@ -251,58 +226,77 @@ void bootloader_main()
|
||||
{
|
||||
ESP_LOGI(TAG, "Espressif ESP32 2nd stage bootloader v. %s", BOOT_VERSION);
|
||||
|
||||
struct flash_hdr fhdr;
|
||||
esp_image_header_t fhdr;
|
||||
bootloader_state_t bs;
|
||||
SpiFlashOpResult spiRet1,spiRet2;
|
||||
ota_select sa,sb;
|
||||
SpiFlashOpResult spiRet1,spiRet2;
|
||||
esp_ota_select_entry_t sa,sb;
|
||||
const esp_ota_select_entry_t *ota_select_map;
|
||||
|
||||
memset(&bs, 0, sizeof(bs));
|
||||
|
||||
ESP_LOGI(TAG, "compile time " __TIME__ );
|
||||
/* close watch dog here */
|
||||
/* disable watch dog here */
|
||||
REG_CLR_BIT( RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN );
|
||||
REG_CLR_BIT( TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN );
|
||||
SPIUnlock();
|
||||
/*register first sector in drom0 page 0 */
|
||||
boot_cache_redirect( 0, 0x5000 );
|
||||
|
||||
memcpy((unsigned int *) &fhdr, MEM_CACHE(0x1000), sizeof(struct flash_hdr) );
|
||||
if(esp_image_load_header(0x1000, &fhdr) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "failed to load bootloader header!");
|
||||
return;
|
||||
}
|
||||
|
||||
print_flash_info(&fhdr);
|
||||
|
||||
if (!load_partition_table(&bs, PARTITION_ADD)) {
|
||||
update_flash_config(&fhdr);
|
||||
|
||||
if (!load_partition_table(&bs)) {
|
||||
ESP_LOGE(TAG, "load partition table error!");
|
||||
return;
|
||||
}
|
||||
|
||||
partition_pos_t load_part_pos;
|
||||
esp_partition_pos_t load_part_pos;
|
||||
|
||||
if (bs.ota_info.offset != 0) { // check if partition table has OTA info partition
|
||||
//ESP_LOGE("OTA info sector handling is not implemented");
|
||||
boot_cache_redirect(bs.ota_info.offset, bs.ota_info.size );
|
||||
memcpy(&sa,MEM_CACHE(bs.ota_info.offset & 0x0000ffff),sizeof(sa));
|
||||
memcpy(&sb,MEM_CACHE((bs.ota_info.offset + 0x1000)&0x0000ffff) ,sizeof(sb));
|
||||
if(sa.ota_seq == 0xFFFFFFFF && sb.ota_seq == 0xFFFFFFFF) {
|
||||
// init status flash
|
||||
load_part_pos = bs.ota[0];
|
||||
sa.ota_seq = 0x01;
|
||||
sa.crc = ota_select_crc(&sa);
|
||||
sb.ota_seq = 0x00;
|
||||
sb.crc = ota_select_crc(&sb);
|
||||
if (bs.ota_info.size < 2 * sizeof(esp_ota_select_entry_t)) {
|
||||
ESP_LOGE(TAG, "ERROR: ota_info partition size %d is too small (minimum %d bytes)", bs.ota_info.size, sizeof(esp_ota_select_entry_t));
|
||||
return;
|
||||
}
|
||||
ota_select_map = bootloader_mmap(bs.ota_info.offset, bs.ota_info.size);
|
||||
if (!ota_select_map) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", bs.ota_info.offset, bs.ota_info.size);
|
||||
return;
|
||||
}
|
||||
sa = ota_select_map[0];
|
||||
sb = ota_select_map[1];
|
||||
bootloader_munmap(ota_select_map);
|
||||
|
||||
Cache_Read_Disable(0);
|
||||
spiRet1 = SPIEraseSector(bs.ota_info.offset/0x1000);
|
||||
spiRet2 = SPIEraseSector(bs.ota_info.offset/0x1000+1);
|
||||
if (spiRet1 != SPI_FLASH_RESULT_OK || spiRet2 != SPI_FLASH_RESULT_OK ) {
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return;
|
||||
}
|
||||
spiRet1 = SPIWrite(bs.ota_info.offset,(uint32_t *)&sa,sizeof(ota_select));
|
||||
spiRet2 = SPIWrite(bs.ota_info.offset + 0x1000,(uint32_t *)&sb,sizeof(ota_select));
|
||||
if (spiRet1 != SPI_FLASH_RESULT_OK || spiRet2 != SPI_FLASH_RESULT_OK ) {
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return;
|
||||
}
|
||||
Cache_Read_Enable(0);
|
||||
if(sa.ota_seq == 0xFFFFFFFF && sb.ota_seq == 0xFFFFFFFF) {
|
||||
// init status flash
|
||||
if (bs.factory.offset != 0) { // if have factory bin,boot factory bin
|
||||
load_part_pos = bs.factory;
|
||||
} else {
|
||||
load_part_pos = bs.ota[0];
|
||||
sa.ota_seq = 0x01;
|
||||
sa.crc = ota_select_crc(&sa);
|
||||
sb.ota_seq = 0x00;
|
||||
sb.crc = ota_select_crc(&sb);
|
||||
|
||||
Cache_Read_Disable(0);
|
||||
spiRet1 = SPIEraseSector(bs.ota_info.offset/0x1000);
|
||||
spiRet2 = SPIEraseSector(bs.ota_info.offset/0x1000+1);
|
||||
if (spiRet1 != SPI_FLASH_RESULT_OK || spiRet2 != SPI_FLASH_RESULT_OK ) {
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return;
|
||||
}
|
||||
spiRet1 = SPIWrite(bs.ota_info.offset,(uint32_t *)&sa,sizeof(esp_ota_select_entry_t));
|
||||
spiRet2 = SPIWrite(bs.ota_info.offset + 0x1000,(uint32_t *)&sb,sizeof(esp_ota_select_entry_t));
|
||||
if (spiRet1 != SPI_FLASH_RESULT_OK || spiRet2 != SPI_FLASH_RESULT_OK ) {
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return;
|
||||
}
|
||||
Cache_Read_Enable(0);
|
||||
}
|
||||
//TODO:write data in ota info
|
||||
} else {
|
||||
if(ota_select_valid(&sa) && ota_select_valid(&sb)) {
|
||||
@@ -326,35 +320,61 @@ void bootloader_main()
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "Loading app partition at offset %08x", load_part_pos);
|
||||
if(fhdr.secury_boot_flag == 0x01) {
|
||||
/* protect the 2nd_boot */
|
||||
if(false == secure_boot()){
|
||||
ESP_LOGE(TAG, "secure boot failed");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOTLOADER_ENABLED
|
||||
/* Generate secure digest from this bootloader to protect future
|
||||
modifications */
|
||||
esp_err_t err = esp_secure_boot_permanently_enable();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Bootloader digest generation failed (%d). SECURE BOOT IS NOT ENABLED.", err);
|
||||
/* Allow booting to continue, as the failure is probably
|
||||
due to user-configured EFUSEs for testing...
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
if(fhdr.encrypt_flag == 0x01) {
|
||||
/* encrypt flash */
|
||||
/* encrypt flash */
|
||||
if (false == flash_encrypt(&bs)) {
|
||||
ESP_LOGE(TAG, "flash encrypt failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// copy sections to RAM, set up caches, and start application
|
||||
// copy loaded segments to RAM, set up caches for mapped segments, and start application
|
||||
unpack_load_app(&load_part_pos);
|
||||
}
|
||||
|
||||
|
||||
void unpack_load_app(const partition_pos_t* partition)
|
||||
static void unpack_load_app(const esp_partition_pos_t* partition)
|
||||
{
|
||||
boot_cache_redirect(partition->offset, partition->size);
|
||||
esp_err_t err;
|
||||
esp_image_header_t image_header;
|
||||
uint32_t image_length;
|
||||
|
||||
uint32_t pos = 0;
|
||||
struct flash_hdr image_header;
|
||||
memcpy(&image_header, MEM_CACHE(pos), sizeof(image_header));
|
||||
pos += sizeof(image_header);
|
||||
/* TODO: verify the app image as part of OTA boot decision, so can have fallbacks */
|
||||
err = esp_image_basic_verify(partition->offset, &image_length);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to verify app image @ 0x%x (%d)", partition->offset, err);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOTLOADER_ENABLED
|
||||
if (esp_secure_boot_enabled()) {
|
||||
ESP_LOGI(TAG, "Verifying app signature @ 0x%x (length 0x%x)", partition->offset, image_length);
|
||||
err = esp_secure_boot_verify_signature(partition->offset, image_length);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "App image @ 0x%x failed signature verification (%d)", partition->offset, err);
|
||||
return;
|
||||
}
|
||||
ESP_LOGD(TAG, "App signature is valid");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (esp_image_load_header(partition->offset, &image_header) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to load app image header @ 0x%x", partition->offset);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t drom_addr = 0;
|
||||
uint32_t drom_load_addr = 0;
|
||||
@@ -363,24 +383,27 @@ void unpack_load_app(const partition_pos_t* partition)
|
||||
uint32_t irom_load_addr = 0;
|
||||
uint32_t irom_size = 0;
|
||||
|
||||
/* Reload the RTC memory sections whenever a non-deepsleep reset
|
||||
is occuring */
|
||||
/* Reload the RTC memory segments whenever a non-deepsleep reset
|
||||
is occurring */
|
||||
bool load_rtc_memory = rtc_get_reset_reason(0) != DEEPSLEEP_RESET;
|
||||
|
||||
ESP_LOGD(TAG, "bin_header: %u %u %u %u %08x", image_header.magic,
|
||||
image_header.blocks,
|
||||
image_header.segment_count,
|
||||
image_header.spi_mode,
|
||||
image_header.spi_size,
|
||||
(unsigned)image_header.entry_addr);
|
||||
|
||||
for (uint32_t section_index = 0;
|
||||
section_index < image_header.blocks;
|
||||
++section_index) {
|
||||
struct block_hdr section_header = {0};
|
||||
memcpy(§ion_header, MEM_CACHE(pos), sizeof(section_header));
|
||||
pos += sizeof(section_header);
|
||||
for (int segment = 0; segment < image_header.segment_count; segment++) {
|
||||
esp_image_segment_header_t segment_header;
|
||||
uint32_t data_offs;
|
||||
if(esp_image_load_segment_header(segment, partition->offset,
|
||||
&image_header, &segment_header,
|
||||
&data_offs) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "failed to load segment header #%d", segment);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t address = section_header.load_addr;
|
||||
const uint32_t address = segment_header.load_addr;
|
||||
bool load = true;
|
||||
bool map = false;
|
||||
if (address == 0x00000000) { // padding, ignore block
|
||||
@@ -392,47 +415,50 @@ void unpack_load_app(const partition_pos_t* partition)
|
||||
}
|
||||
|
||||
if (address >= DROM_LOW && address < DROM_HIGH) {
|
||||
ESP_LOGD(TAG, "found drom section, map from %08x to %08x", pos,
|
||||
section_header.load_addr);
|
||||
drom_addr = partition->offset + pos - sizeof(section_header);
|
||||
drom_load_addr = section_header.load_addr;
|
||||
drom_size = section_header.data_len + sizeof(section_header);
|
||||
ESP_LOGD(TAG, "found drom segment, map from %08x to %08x", data_offs,
|
||||
segment_header.load_addr);
|
||||
drom_addr = data_offs;
|
||||
drom_load_addr = segment_header.load_addr;
|
||||
drom_size = segment_header.data_len + sizeof(segment_header);
|
||||
load = false;
|
||||
map = true;
|
||||
}
|
||||
|
||||
if (address >= IROM_LOW && address < IROM_HIGH) {
|
||||
ESP_LOGD(TAG, "found irom section, map from %08x to %08x", pos,
|
||||
section_header.load_addr);
|
||||
irom_addr = partition->offset + pos - sizeof(section_header);
|
||||
irom_load_addr = section_header.load_addr;
|
||||
irom_size = section_header.data_len + sizeof(section_header);
|
||||
ESP_LOGD(TAG, "found irom segment, map from %08x to %08x", data_offs,
|
||||
segment_header.load_addr);
|
||||
irom_addr = data_offs;
|
||||
irom_load_addr = segment_header.load_addr;
|
||||
irom_size = segment_header.data_len + sizeof(segment_header);
|
||||
load = false;
|
||||
map = true;
|
||||
}
|
||||
|
||||
if(!load_rtc_memory && address >= RTC_IRAM_LOW && address < RTC_IRAM_HIGH) {
|
||||
ESP_LOGD(TAG, "Skipping RTC code section at %08x\n", pos);
|
||||
load = false;
|
||||
}
|
||||
|
||||
if(!load_rtc_memory && address >= RTC_DATA_LOW && address < RTC_DATA_HIGH) {
|
||||
ESP_LOGD(TAG, "Skipping RTC data section at %08x\n", pos);
|
||||
load = false;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "section %d: paddr=0x%08x vaddr=0x%08x size=0x%05x (%6d) %s", section_index, pos,
|
||||
section_header.load_addr, section_header.data_len, section_header.data_len, (load)?"load":(map)?"map":"");
|
||||
|
||||
if (!load) {
|
||||
pos += section_header.data_len;
|
||||
continue;
|
||||
if (!load_rtc_memory && address >= RTC_IRAM_LOW && address < RTC_IRAM_HIGH) {
|
||||
ESP_LOGD(TAG, "Skipping RTC code segment at %08x\n", data_offs);
|
||||
load = false;
|
||||
}
|
||||
|
||||
memcpy((void*) section_header.load_addr, MEM_CACHE(pos), section_header.data_len);
|
||||
pos += section_header.data_len;
|
||||
if (!load_rtc_memory && address >= RTC_DATA_LOW && address < RTC_DATA_HIGH) {
|
||||
ESP_LOGD(TAG, "Skipping RTC data segment at %08x\n", data_offs);
|
||||
load = false;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "segment %d: paddr=0x%08x vaddr=0x%08x size=0x%05x (%6d) %s", segment, data_offs - sizeof(esp_image_segment_header_t),
|
||||
segment_header.load_addr, segment_header.data_len, segment_header.data_len, (load)?"load":(map)?"map":"");
|
||||
|
||||
if (load) {
|
||||
const void *data = bootloader_mmap(data_offs, segment_header.data_len);
|
||||
if(!data) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%xc, 0x%x) failed",
|
||||
data_offs, segment_header.data_len);
|
||||
return;
|
||||
}
|
||||
memcpy((void *)segment_header.load_addr, data, segment_header.data_len);
|
||||
bootloader_munmap(data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
set_cache_and_start_app(drom_addr,
|
||||
drom_load_addr,
|
||||
drom_size,
|
||||
@@ -442,7 +468,7 @@ void unpack_load_app(const partition_pos_t* partition)
|
||||
image_header.entry_addr);
|
||||
}
|
||||
|
||||
void IRAM_ATTR set_cache_and_start_app(
|
||||
void set_cache_and_start_app(
|
||||
uint32_t drom_addr,
|
||||
uint32_t drom_load_addr,
|
||||
uint32_t drom_size,
|
||||
@@ -453,9 +479,7 @@ void IRAM_ATTR set_cache_and_start_app(
|
||||
{
|
||||
ESP_LOGD(TAG, "configure drom and irom and start");
|
||||
Cache_Read_Disable( 0 );
|
||||
Cache_Read_Disable( 1 );
|
||||
Cache_Flush( 0 );
|
||||
Cache_Flush( 1 );
|
||||
uint32_t drom_page_count = (drom_size + 64*1024 - 1) / (64*1024); // round up to 64k
|
||||
ESP_LOGV(TAG, "d mmu set paddr=%08x vaddr=%08x size=%d n=%d", drom_addr & 0xffff0000, drom_load_addr & 0xffff0000, drom_size, drom_page_count );
|
||||
int rc = cache_flash_mmu_set( 0, 0, drom_load_addr & 0xffff0000, drom_addr & 0xffff0000, 64, drom_page_count );
|
||||
@@ -471,7 +495,8 @@ void IRAM_ATTR set_cache_and_start_app(
|
||||
REG_CLR_BIT( DPORT_PRO_CACHE_CTRL1_REG, (DPORT_PRO_CACHE_MASK_IRAM0) | (DPORT_PRO_CACHE_MASK_IRAM1 & 0) | (DPORT_PRO_CACHE_MASK_IROM0 & 0) | DPORT_PRO_CACHE_MASK_DROM0 | DPORT_PRO_CACHE_MASK_DRAM1 );
|
||||
REG_CLR_BIT( DPORT_APP_CACHE_CTRL1_REG, (DPORT_APP_CACHE_MASK_IRAM0) | (DPORT_APP_CACHE_MASK_IRAM1 & 0) | (DPORT_APP_CACHE_MASK_IROM0 & 0) | DPORT_APP_CACHE_MASK_DROM0 | DPORT_APP_CACHE_MASK_DRAM1 );
|
||||
Cache_Read_Enable( 0 );
|
||||
Cache_Read_Enable( 1 );
|
||||
|
||||
// Application will need to do Cache_Flush(1) and Cache_Read_Enable(1)
|
||||
|
||||
ESP_LOGD(TAG, "start: 0x%08x", entry_addr);
|
||||
typedef void (*entry_t)(void);
|
||||
@@ -482,67 +507,84 @@ void IRAM_ATTR set_cache_and_start_app(
|
||||
(*entry)();
|
||||
}
|
||||
|
||||
static void update_flash_config(const esp_image_header_t* pfhdr)
|
||||
{
|
||||
uint32_t size;
|
||||
switch(pfhdr->spi_size) {
|
||||
case ESP_IMAGE_FLASH_SIZE_1MB:
|
||||
size = 1;
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_2MB:
|
||||
size = 2;
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_4MB:
|
||||
size = 4;
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_8MB:
|
||||
size = 8;
|
||||
break;
|
||||
case ESP_IMAGE_FLASH_SIZE_16MB:
|
||||
size = 16;
|
||||
break;
|
||||
default:
|
||||
size = 2;
|
||||
}
|
||||
Cache_Read_Disable( 0 );
|
||||
// Set flash chip size
|
||||
SPIParamCfg(g_rom_flashchip.deviceId, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
|
||||
// TODO: set mode
|
||||
// TODO: set frequency
|
||||
Cache_Flush(0);
|
||||
Cache_Read_Enable( 0 );
|
||||
}
|
||||
|
||||
void print_flash_info(struct flash_hdr* pfhdr)
|
||||
void print_flash_info(const esp_image_header_t* phdr)
|
||||
{
|
||||
#if (BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_NOTICE)
|
||||
|
||||
struct flash_hdr fhdr = *pfhdr;
|
||||
|
||||
ESP_LOGD(TAG, "magic %02x", fhdr.magic );
|
||||
ESP_LOGD(TAG, "blocks %02x", fhdr.blocks );
|
||||
ESP_LOGD(TAG, "spi_mode %02x", fhdr.spi_mode );
|
||||
ESP_LOGD(TAG, "spi_speed %02x", fhdr.spi_speed );
|
||||
ESP_LOGD(TAG, "spi_size %02x", fhdr.spi_size );
|
||||
ESP_LOGD(TAG, "magic %02x", phdr->magic );
|
||||
ESP_LOGD(TAG, "segments %02x", phdr->segment_count );
|
||||
ESP_LOGD(TAG, "spi_mode %02x", phdr->spi_mode );
|
||||
ESP_LOGD(TAG, "spi_speed %02x", phdr->spi_speed );
|
||||
ESP_LOGD(TAG, "spi_size %02x", phdr->spi_size );
|
||||
|
||||
const char* str;
|
||||
switch ( fhdr.spi_speed ) {
|
||||
case SPI_SPEED_40M:
|
||||
switch ( phdr->spi_speed ) {
|
||||
case ESP_IMAGE_SPI_SPEED_40M:
|
||||
str = "40MHz";
|
||||
break;
|
||||
|
||||
case SPI_SPEED_26M:
|
||||
case ESP_IMAGE_SPI_SPEED_26M:
|
||||
str = "26.7MHz";
|
||||
break;
|
||||
|
||||
case SPI_SPEED_20M:
|
||||
case ESP_IMAGE_SPI_SPEED_20M:
|
||||
str = "20MHz";
|
||||
break;
|
||||
|
||||
case SPI_SPEED_80M:
|
||||
case ESP_IMAGE_SPI_SPEED_80M:
|
||||
str = "80MHz";
|
||||
break;
|
||||
|
||||
default:
|
||||
str = "20MHz";
|
||||
break;
|
||||
}
|
||||
ESP_LOGI(TAG, "SPI Speed : %s", str );
|
||||
|
||||
|
||||
|
||||
switch ( fhdr.spi_mode ) {
|
||||
case SPI_MODE_QIO:
|
||||
switch ( phdr->spi_mode ) {
|
||||
case ESP_IMAGE_SPI_MODE_QIO:
|
||||
str = "QIO";
|
||||
break;
|
||||
|
||||
case SPI_MODE_QOUT:
|
||||
case ESP_IMAGE_SPI_MODE_QOUT:
|
||||
str = "QOUT";
|
||||
break;
|
||||
|
||||
case SPI_MODE_DIO:
|
||||
case ESP_IMAGE_SPI_MODE_DIO:
|
||||
str = "DIO";
|
||||
break;
|
||||
|
||||
case SPI_MODE_DOUT:
|
||||
case ESP_IMAGE_SPI_MODE_DOUT:
|
||||
str = "DOUT";
|
||||
break;
|
||||
|
||||
case SPI_MODE_FAST_READ:
|
||||
case ESP_IMAGE_SPI_MODE_FAST_READ:
|
||||
str = "FAST READ";
|
||||
break;
|
||||
|
||||
case SPI_MODE_SLOW_READ:
|
||||
case ESP_IMAGE_SPI_MODE_SLOW_READ:
|
||||
str = "SLOW READ";
|
||||
break;
|
||||
default:
|
||||
@@ -551,31 +593,24 @@ void print_flash_info(struct flash_hdr* pfhdr)
|
||||
}
|
||||
ESP_LOGI(TAG, "SPI Mode : %s", str );
|
||||
|
||||
|
||||
|
||||
switch ( fhdr.spi_size ) {
|
||||
case SPI_SIZE_1MB:
|
||||
switch ( phdr->spi_size ) {
|
||||
case ESP_IMAGE_FLASH_SIZE_1MB:
|
||||
str = "1MB";
|
||||
break;
|
||||
|
||||
case SPI_SIZE_2MB:
|
||||
case ESP_IMAGE_FLASH_SIZE_2MB:
|
||||
str = "2MB";
|
||||
break;
|
||||
|
||||
case SPI_SIZE_4MB:
|
||||
case ESP_IMAGE_FLASH_SIZE_4MB:
|
||||
str = "4MB";
|
||||
break;
|
||||
|
||||
case SPI_SIZE_8MB:
|
||||
case ESP_IMAGE_FLASH_SIZE_8MB:
|
||||
str = "8MB";
|
||||
break;
|
||||
|
||||
case SPI_SIZE_16MB:
|
||||
case ESP_IMAGE_FLASH_SIZE_16MB:
|
||||
str = "16MB";
|
||||
break;
|
||||
|
||||
default:
|
||||
str = "1MB";
|
||||
str = "2MB";
|
||||
break;
|
||||
}
|
||||
ESP_LOGI(TAG, "SPI Flash Size : %s", str );
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
#
|
||||
# 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
|
||||
COMPONENT_ADD_LDFLAGS := -L $(COMPONENT_PATH) -lmain -T esp32.bootloader.ld -T $(IDF_PATH)/components/esp32/ld/esp32.rom.ld
|
||||
|
||||
include $(IDF_PATH)/make/component_common.mk
|
||||
|
||||
@@ -15,7 +15,7 @@ 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.*/
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "esp_types.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#include "rom/cache.h"
|
||||
#include "rom/ets_sys.h"
|
||||
@@ -30,6 +31,7 @@
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "bootloader_config.h"
|
||||
#include "esp_image_format.h"
|
||||
|
||||
static const char* TAG = "flash_encrypt";
|
||||
|
||||
@@ -90,103 +92,97 @@ bool flash_encrypt_write(uint32_t pos, uint32_t len)
|
||||
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);
|
||||
esp_err_t err;
|
||||
uint32_t image_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);
|
||||
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;
|
||||
}
|
||||
if ((count % 2) == 0) {
|
||||
/* encrypt iv and abstract */
|
||||
if (false == flash_encrypt_write(0, SPI_SEC_SIZE)) {
|
||||
ESP_LOGE(TAG, "encrypt iv and abstract error");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* encrypt bootloader image */
|
||||
err = esp_image_basic_verify(0x1000, &image_len);
|
||||
if(err == ESP_OK && image_len != 0) {
|
||||
if (false == flash_encrypt_write(0x1000, image_len)) {
|
||||
ESP_LOGE(TAG, "encrypt 2nd boot error");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "2nd boot len 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;
|
||||
}
|
||||
if (false == flash_encrypt_write(ESP_PARTITION_TABLE_ADDR, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(bs->factory.offset != 0 && bs->factory.size != 0) {
|
||||
ESP_LOGD(TAG, "have factory bin");
|
||||
if (false == flash_encrypt_write(bs->factory.offset, bs->factory.size)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(bs->test.offset != 0 && bs->test.size != 0) {
|
||||
ESP_LOGD(TAG, "have test bin");
|
||||
if (false == flash_encrypt_write(bs->test.offset, bs->test.size)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if(bs->ota[i].offset != 0 && bs->ota[i].size != 0) {
|
||||
ESP_LOGD(TAG, "have ota[%d] bin",i);
|
||||
if (false == flash_encrypt_write(bs->ota[i].offset, bs->ota[i].size)) {
|
||||
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;
|
||||
}
|
||||
if (false == flash_encrypt_write(bs->ota_info.offset, 2*SPI_SEC_SIZE)) {
|
||||
ESP_LOGE(TAG, "encrypt ota info error");
|
||||
return false;
|
||||
}
|
||||
|
||||
REG_SET_FIELD(EFUSE_BLK0_WDATA0_REG, EFUSE_FLASH_CRYPT_CNT, 0x04);
|
||||
REG_WRITE(EFUSE_CONF_REG, 0x5A5A); /* efuse_pgm_op_ena, force no rd/wr disable */
|
||||
REG_WRITE(EFUSE_CMD_REG, 0x02); /* efuse_pgm_cmd */
|
||||
while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_pagm_cmd=0 */
|
||||
ESP_LOGW(TAG, "burn flash_crypt_cnt");
|
||||
REG_WRITE(EFUSE_CONF_REG, 0x5AA5); /* efuse_read_op_ena, release force */
|
||||
REG_WRITE(EFUSE_CMD_REG, 0x01); /* efuse_read_cmd */
|
||||
while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_read_cmd=0 */
|
||||
return true;
|
||||
} else {
|
||||
ESP_LOGI(TAG, "flash already encrypted.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_attr.h"
|
||||
#include "esp_types.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "rom/cache.h"
|
||||
#include "rom/ets_sys.h"
|
||||
#include "rom/spi_flash.h"
|
||||
#include "rom/secure_boot.h"
|
||||
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "bootloader_config.h"
|
||||
|
||||
static const char* TAG = "secure_boot";
|
||||
|
||||
/**
|
||||
* @function : secure_boot_generate
|
||||
* @description: generate boot abstract & iv
|
||||
*
|
||||
* @inputs: bool
|
||||
*/
|
||||
bool secure_boot_generate(uint32_t bin_len){
|
||||
SpiFlashOpResult spiRet;
|
||||
uint16_t i;
|
||||
uint32_t buf[32];
|
||||
if (bin_len % 128 != 0) {
|
||||
bin_len = (bin_len / 128 + 1) * 128;
|
||||
}
|
||||
ets_secure_boot_start();
|
||||
ets_secure_boot_rd_iv(buf);
|
||||
ets_secure_boot_hash(NULL);
|
||||
Cache_Read_Disable(0);
|
||||
/* iv stored in sec 0 */
|
||||
spiRet = SPIEraseSector(0);
|
||||
if (spiRet != SPI_FLASH_RESULT_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return false;
|
||||
}
|
||||
/* write iv to flash, 0x0000, 128 bytes (1024 bits) */
|
||||
spiRet = SPIWrite(0, buf, 128);
|
||||
if (spiRet != SPI_FLASH_RESULT_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return false;
|
||||
}
|
||||
ESP_LOGD(TAG, "write iv to flash.");
|
||||
Cache_Read_Enable(0);
|
||||
/* read 4K code image from flash, for test */
|
||||
for (i = 0; i < bin_len; i+=128) {
|
||||
ets_secure_boot_hash((uint32_t *)(0x3f400000 + 0x1000 + i));
|
||||
}
|
||||
|
||||
ets_secure_boot_obtain();
|
||||
ets_secure_boot_rd_abstract(buf);
|
||||
ets_secure_boot_finish();
|
||||
Cache_Read_Disable(0);
|
||||
/* write abstract to flash, 0x0080, 64 bytes (512 bits) */
|
||||
spiRet = SPIWrite(0x80, buf, 64);
|
||||
if (spiRet != SPI_FLASH_RESULT_OK) {
|
||||
ESP_LOGE(TAG, SPI_ERROR_LOG);
|
||||
return false;
|
||||
}
|
||||
ESP_LOGD(TAG, "write abstract to flash.");
|
||||
Cache_Read_Enable(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @function : secure_boot
|
||||
* @description: protect boot code in flash
|
||||
*
|
||||
* @inputs: bool
|
||||
*/
|
||||
bool secure_boot(void){
|
||||
uint32_t bin_len = 0;
|
||||
if (REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_RD_ABS_DONE_0)
|
||||
{
|
||||
ESP_LOGD(TAG, "already secure boot !");
|
||||
return true;
|
||||
} else {
|
||||
boot_cache_redirect( 0, 64*1024);
|
||||
bin_len = get_bin_len((uint32_t)MEM_CACHE(0x1000));
|
||||
if (bin_len == 0) {
|
||||
ESP_LOGE(TAG, "boot len is error");
|
||||
return false;
|
||||
}
|
||||
if (false == secure_boot_generate(bin_len)){
|
||||
ESP_LOGE(TAG, "secure boot generate failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
REG_SET_BIT(EFUSE_BLK0_WDATA6_REG, EFUSE_RD_ABS_DONE_0);
|
||||
REG_WRITE(EFUSE_CONF_REG, 0x5A5A); /* efuse_pgm_op_ena, force no rd/wr disable */
|
||||
REG_WRITE(EFUSE_CMD_REG, 0x02); /* efuse_pgm_cmd */
|
||||
while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_pagm_cmd=0 */
|
||||
ESP_LOGW(TAG, "burn abstract_done_0");
|
||||
REG_WRITE(EFUSE_CONF_REG, 0x5AA5); /* efuse_read_op_ena, release force */
|
||||
REG_WRITE(EFUSE_CMD_REG, 0x01); /* efuse_read_cmd */
|
||||
while (REG_READ(EFUSE_CMD_REG)); /* wait for efuse_read_cmd=0 */
|
||||
ESP_LOGI(TAG, "read EFUSE_BLK0_RDATA6 %x", REG_READ(EFUSE_BLK0_RDATA6_REG));
|
||||
return true;
|
||||
|
||||
}
|
||||
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.)
|
||||
35
components/bootloader_support/component.mk
Executable file
35
components/bootloader_support/component.mk
Executable file
@@ -0,0 +1,35 @@
|
||||
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_BOOTLOADER_ENABLED
|
||||
|
||||
# this path is created relative to the component build directory
|
||||
SECURE_BOOT_VERIFICATION_KEY := $(abspath signature_verification_key.bin)
|
||||
|
||||
$(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
|
||||
|
||||
$(SECURE_BOOT_VERIFICATION_KEY): $(SECURE_BOOT_SIGNING_KEY)
|
||||
$(ESPSECUREPY) extract_public_key --keyfile $< $@
|
||||
|
||||
COMPONENT_EXTRA_CLEAN += $(SECURE_BOOT_VERIFICATION_KEY)
|
||||
|
||||
COMPONENT_EMBED_FILES := $(SECURE_BOOT_VERIFICATION_KEY)
|
||||
|
||||
endif
|
||||
132
components/bootloader_support/include/esp_image_format.h
Normal file
132
components/bootloader_support/include/esp_image_format.h
Normal file
@@ -0,0 +1,132 @@
|
||||
// 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.
|
||||
*
|
||||
* @param src_addr Address in flash to load image header. Must be 4 byte aligned.
|
||||
* @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, esp_image_header_t *image_header);
|
||||
|
||||
/**
|
||||
* @brief Read the segment header and data offset of a segment in the image.
|
||||
*
|
||||
* @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[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, esp_image_segment_header_t *segment_header, uint32_t *segment_data_offset);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return length of an image in flash. Non-cryptographically validates image integrity in the process.
|
||||
*
|
||||
* If the image has a secure boot signature appended, the signature is not checked and this length is not included in the result.
|
||||
*
|
||||
* Image validation checks:
|
||||
* - Magic byte
|
||||
* - No single segment longer than 16MB
|
||||
* - Total image no longer than 16MB
|
||||
* - 8 bit image checksum is valid
|
||||
*
|
||||
* @param src_addr Offset of the start of the image in flash. Must be 4 byte aligned.
|
||||
* @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, 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
|
||||
75
components/bootloader_support/include/esp_secure_boot.h
Normal file
75
components/bootloader_support/include/esp_secure_boot.h
Normal file
@@ -0,0 +1,75 @@
|
||||
// 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.
|
||||
*
|
||||
* @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);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,69 @@
|
||||
// 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>
|
||||
|
||||
/* 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 Both src and dest 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
|
||||
*
|
||||
* @return esp_err_t
|
||||
*/
|
||||
esp_err_t bootloader_flash_read(size_t src_addr, void *dest, size_t size);
|
||||
|
||||
#endif
|
||||
122
components/bootloader_support/src/bootloader_flash.c
Normal file
122
components/bootloader_support/src/bootloader_flash.c
Normal file
@@ -0,0 +1,122 @@
|
||||
// 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 */
|
||||
|
||||
#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)
|
||||
{
|
||||
return spi_flash_read(src, dest, size);
|
||||
}
|
||||
|
||||
#else
|
||||
/* Bootloader version, uses ROM functions only */
|
||||
#include <rom/spi_flash.h>
|
||||
#include <rom/cache.h>
|
||||
|
||||
static const char *TAG = "bootloader_flash";
|
||||
|
||||
static bool mapped;
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
uint32_t src_addr_aligned = src_addr & 0xffff0000;
|
||||
uint32_t count = (size + (src_addr - src_addr_aligned) + 0xffff) / 0x10000;
|
||||
Cache_Read_Disable(0);
|
||||
Cache_Flush(0);
|
||||
ESP_LOGD(TAG, "mmu set paddr=%08x count=%d", src_addr_aligned, count );
|
||||
cache_flash_mmu_set( 0, 0, 0x3f400000, src_addr_aligned, 64, count );
|
||||
Cache_Read_Enable( 0 );
|
||||
|
||||
mapped = true;
|
||||
|
||||
return (void *)(0x3f400000 + (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;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t bootloader_flash_read(size_t src_addr, void *dest, size_t size)
|
||||
{
|
||||
if(src_addr & 3) {
|
||||
ESP_LOGE(TAG, "bootloader_flash_read src_addr 0x%x not 4-byte aligned", src_addr);
|
||||
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;
|
||||
}
|
||||
|
||||
Cache_Read_Disable(0);
|
||||
Cache_Flush(0);
|
||||
SpiFlashOpResult r = SPIRead(src_addr, dest, size);
|
||||
Cache_Read_Enable(0);
|
||||
|
||||
switch(r) {
|
||||
case SPI_FLASH_RESULT_OK:
|
||||
return ESP_OK;
|
||||
case SPI_FLASH_RESULT_ERR:
|
||||
return ESP_ERR_FLASH_OP_FAIL;
|
||||
case SPI_FLASH_RESULT_TIMEOUT:
|
||||
return ESP_ERR_FLASH_OP_TIMEOUT;
|
||||
default:
|
||||
return ESP_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
161
components/bootloader_support/src/esp_image_format.c
Normal file
161
components/bootloader_support/src/esp_image_format.c
Normal file
@@ -0,0 +1,161 @@
|
||||
// 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, 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));
|
||||
|
||||
if (err == ESP_OK) {
|
||||
if (image_header->magic != ESP_IMAGE_HEADER_MAGIC) {
|
||||
ESP_LOGE(TAG, "image at 0x%x has invalid magic byte", src_addr);
|
||||
err = ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
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, 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) {
|
||||
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));
|
||||
if (err == ESP_OK) {
|
||||
if ((segment_header->data_len & 3) != 0
|
||||
|| segment_header->data_len >= SIXTEEN_MB) {
|
||||
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, uint32_t *p_length)
|
||||
{
|
||||
esp_err_t err;
|
||||
uint8_t buf[16];
|
||||
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;
|
||||
const uint8_t *segment_data;
|
||||
uint32_t end_addr;
|
||||
uint32_t length;
|
||||
|
||||
if (p_length != NULL) {
|
||||
*p_length = 0;
|
||||
}
|
||||
|
||||
err = esp_image_load_header(src_addr, &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,
|
||||
&segment_header, &segment_data_offs);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
segment_data = bootloader_mmap(segment_data_offs, segment_header.data_len);
|
||||
if (segment_data == NULL) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", segment_data_offs, segment_header.data_len);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
for(int i = 0; i < segment_header.data_len; i++) {
|
||||
checksum ^= segment_data[i];
|
||||
}
|
||||
bootloader_munmap(segment_data);
|
||||
}
|
||||
|
||||
/* End of image, verify checksum */
|
||||
end_addr = segment_data_offs + segment_header.data_len;
|
||||
|
||||
if (end_addr < src_addr) {
|
||||
ESP_LOGE(TAG, "image offset has wrapped");
|
||||
return ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
|
||||
length = end_addr - src_addr;
|
||||
if (length >= SIXTEEN_MB) {
|
||||
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);
|
||||
if (checksum != buf[15]) {
|
||||
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;
|
||||
}
|
||||
222
components/bootloader_support/src/secure_boot.c
Normal file
222
components/bootloader_support/src/secure_boot.c
Normal file
@@ -0,0 +1,222 @@
|
||||
// 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_flash.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_secure_boot.h"
|
||||
|
||||
static const char* TAG = "secure_boot";
|
||||
|
||||
#define HASH_BLOCK_SIZE 128
|
||||
#define IV_LEN HASH_BLOCK_SIZE
|
||||
#define DIGEST_LEN 64
|
||||
|
||||
/**
|
||||
* @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){
|
||||
SpiFlashOpResult spiRet;
|
||||
/* buffer is uint32_t not uint8_t to meet ROM SPI API signature */
|
||||
uint32_t buf[IV_LEN / sizeof(uint32_t)];
|
||||
const void *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 % HASH_BLOCK_SIZE != 0) {
|
||||
image_len = (image_len / HASH_BLOCK_SIZE + 1) * HASH_BLOCK_SIZE;
|
||||
}
|
||||
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 erase failed %d", spiRet);
|
||||
return false;
|
||||
}
|
||||
Cache_Read_Enable(0);
|
||||
|
||||
/* write iv to flash, 0x0000, 128 bytes (1024 bits) */
|
||||
ESP_LOGD(TAG, "write iv to flash.");
|
||||
spiRet = SPIWrite(0, buf, IV_LEN);
|
||||
if (spiRet != SPI_FLASH_RESULT_OK)
|
||||
{
|
||||
ESP_LOGE(TAG, "SPI write failed %d", spiRet);
|
||||
return false;
|
||||
}
|
||||
bzero(buf, sizeof(buf));
|
||||
|
||||
/* 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+= HASH_BLOCK_SIZE) {
|
||||
ets_secure_boot_hash(image + i/sizeof(void *));
|
||||
}
|
||||
bootloader_munmap(image);
|
||||
|
||||
ets_secure_boot_obtain();
|
||||
ets_secure_boot_rd_abstract(buf);
|
||||
ets_secure_boot_finish();
|
||||
|
||||
ESP_LOGD(TAG, "write digest to flash.");
|
||||
spiRet = SPIWrite(0x80, buf, DIGEST_LEN);
|
||||
if (spiRet != SPI_FLASH_RESULT_OK) {
|
||||
ESP_LOGE(TAG, "SPI write failed %d", spiRet);
|
||||
return false;
|
||||
}
|
||||
ESP_LOGD(TAG, "write digest to flash.");
|
||||
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!");
|
||||
#else
|
||||
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 */
|
||||
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 */
|
||||
#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, &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...");
|
||||
/* reuse the secure boot IV generation function to generate
|
||||
the key, as this generator uses the hardware RNG. */
|
||||
uint32_t buf[32];
|
||||
ets_secure_boot_start();
|
||||
ets_secure_boot_rd_iv(buf);
|
||||
ets_secure_boot_finish();
|
||||
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.");
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT_DISABLE_JTAG
|
||||
ESP_LOGI(TAG, "disabling JTAG...");
|
||||
new_wdata6 |= EFUSE_RD_DISABLE_JTAG;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT_DISABLE_UART_BOOTLOADER
|
||||
ESP_LOGI(TAG, "disabling UART bootloader...");
|
||||
new_wdata6 |= EFUSE_RD_CONSOLE_DEBUG_DISABLE_S;
|
||||
#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;
|
||||
}
|
||||
}
|
||||
107
components/bootloader_support/src/secure_boot_signatures.c
Normal file
107
components/bootloader_support/src/secure_boot_signatures.c
Normal file
@@ -0,0 +1,107 @@
|
||||
// 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
|
||||
|
||||
typedef struct {
|
||||
uint32_t version;
|
||||
uint8_t signature[64];
|
||||
} signature_block_t;
|
||||
|
||||
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 signature_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(signature_block_t));
|
||||
if(data == NULL) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr, length+sizeof(signature_block_t));
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
sigblock = (const signature_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;
|
||||
}
|
||||
@@ -8,6 +8,12 @@ config BT_ENABLED
|
||||
help
|
||||
This compiles in the low-level BT stack.
|
||||
|
||||
config BTC_TASK_STACK_SIZE
|
||||
int "BT event (callback to application) task stack size"
|
||||
default 2048
|
||||
help
|
||||
This select btc task stack size
|
||||
|
||||
#config BT_BTLE
|
||||
# bool "Enable BTLE"
|
||||
# depends on BT_ENABLED
|
||||
|
||||
66
components/bt/bluedroid/api/esp_blufi_api.c
Normal file
66
components/bt/bluedroid/api/esp_blufi_api.c
Normal file
@@ -0,0 +1,66 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
#include "esp_blufi_api.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_bt_main.h"
|
||||
#include "btc_task.h"
|
||||
#include "btc_blufi_prf.h"
|
||||
#include "btc_manage.h"
|
||||
#include "btc_main.h"
|
||||
#include "future.h"
|
||||
|
||||
esp_err_t esp_blufi_register_callback(esp_profile_cb_t callback)
|
||||
{
|
||||
return (btc_profile_cb_set(BTC_PID_BLUFI, callback) == 0 ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_blufi_send_config_state(esp_blufi_config_state_t state)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_blufi_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = BTC_BLUFI_ACT_SEND_CFG_STATE;
|
||||
arg.cfg_state.state = state;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_blufi_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_blufi_profile_init(void)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
157
components/bt/bluedroid/api/esp_bt_main.c
Normal file
157
components/bt/bluedroid/api/esp_bt_main.c
Normal file
@@ -0,0 +1,157 @@
|
||||
// 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 "future.h"
|
||||
|
||||
static bool esp_already_enable = false;
|
||||
static bool esp_already_init = false;
|
||||
|
||||
esp_err_t esp_enable_bluetooth(void)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
future_t **future_p;
|
||||
|
||||
if (esp_already_enable) {
|
||||
LOG_ERROR("%s already enable\n", __func__);
|
||||
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("%s failed\n", __func__);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_MAIN_INIT;
|
||||
msg.act = BTC_MAIN_ACT_ENABLE;
|
||||
btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
|
||||
if (future_await(*future_p) == FUTURE_FAIL) {
|
||||
LOG_ERROR("%s failed\n", __func__);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_already_enable = true;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_disable_bluetooth(void)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
future_t **future_p;
|
||||
|
||||
if (!esp_already_enable) {
|
||||
LOG_ERROR("%s already disable\n", __func__);
|
||||
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("%s failed\n", __func__);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_MAIN_INIT;
|
||||
msg.act = BTC_MAIN_ACT_DISABLE;
|
||||
btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
|
||||
if (future_await(*future_p) == FUTURE_FAIL) {
|
||||
LOG_ERROR("%s failed\n", __func__);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_already_enable = false;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_init_bluetooth(void)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
future_t **future_p;
|
||||
|
||||
if (esp_already_init) {
|
||||
LOG_ERROR("%s already init\n", __func__);
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
future_p = btc_main_get_future_p(BTC_MAIN_INIT_FUTURE);
|
||||
*future_p = future_new();
|
||||
if (*future_p == NULL) {
|
||||
LOG_ERROR("%s failed\n", __func__);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
btc_init();
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_MAIN_INIT;
|
||||
msg.act = BTC_MAIN_ACT_INIT;
|
||||
btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
|
||||
if (future_await(*future_p) == FUTURE_FAIL) {
|
||||
LOG_ERROR("%s failed\n", __func__);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_already_init = true;;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_deinit_bluetooth(void)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
future_t **future_p;
|
||||
|
||||
if (!esp_already_init) {
|
||||
LOG_ERROR("%s already deinit\n", __func__);
|
||||
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("%s failed\n", __func__);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_MAIN_INIT;
|
||||
msg.act = BTC_MAIN_ACT_DEINIT;
|
||||
btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
|
||||
if (future_await(*future_p) == FUTURE_FAIL) {
|
||||
LOG_ERROR("%s failed\n", __func__);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_deinit();
|
||||
|
||||
esp_already_init = false;
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
207
components/bt/bluedroid/api/esp_gap_ble_api.c
Normal file
207
components/bt/bluedroid/api/esp_gap_ble_api.c
Normal file
@@ -0,0 +1,207 @@
|
||||
// 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_gap_ble_api.h"
|
||||
#include "bta_api.h"
|
||||
#include "bt_trace.h"
|
||||
#include "btc_manage.h"
|
||||
#include "btc_gap_ble.h"
|
||||
|
||||
|
||||
esp_err_t esp_ble_gap_register_callback(esp_profile_cb_t callback)
|
||||
{
|
||||
return (btc_profile_cb_set(BTC_PID_GAP_BLE, callback) == 0 ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_ble_gap_config_adv_data(esp_ble_adv_data_t *adv_data)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
if (adv_data == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (adv_data->service_uuid_len & 0xf) { //not 16*n
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_CFG_ADV_DATA;
|
||||
memcpy(&arg.cfg_adv_data.adv_data, adv_data, sizeof(esp_ble_adv_data_t));
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), btc_gap_ble_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
|
||||
}
|
||||
|
||||
|
||||
esp_err_t esp_ble_gap_set_scan_params(esp_ble_scan_params_t *scan_params)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
if (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;
|
||||
|
||||
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;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_CONFIG_LOCAL_PRIVACY;
|
||||
arg.cfg_local_privacy.privacy_enable = privacy_enable;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gap_set_device_name(const char *name)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
if (strlen(name) > ESP_GAP_DEVICE_NAME_MAX) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_ACT_SET_DEV_NAME;
|
||||
strcpy(arg.set_dev_name.device_name, name);
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
uint8_t *esp_ble_resolve_adv_data( uint8_t *adv_data, uint8_t type, uint8_t *length)
|
||||
{
|
||||
if (((type < ESP_BLE_AD_TYPE_FLAG) || (type > ESP_BLE_AD_TYPE_128SERVICE_DATA)) &&
|
||||
(type != ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE)) {
|
||||
LOG_ERROR("the eir type not define, type = %x\n", type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (adv_data == NULL) {
|
||||
LOG_ERROR("Invalid p_eir data.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (BTM_CheckAdvData( adv_data, type, length));
|
||||
}
|
||||
|
||||
368
components/bt/bluedroid/api/esp_gattc_api.c
Normal file
368
components/bt/bluedroid/api/esp_gattc_api.c
Normal file
@@ -0,0 +1,368 @@
|
||||
// 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 "btc_manage.h"
|
||||
#include "btc_gattc.h"
|
||||
|
||||
esp_err_t esp_ble_gattc_register_callback(esp_profile_cb_t callback)
|
||||
{
|
||||
if (callback == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
btc_profile_cb_set(BTC_PID_GATTC, callback);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_app_register(uint16_t app_id)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
//if (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_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 gatt_if)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_APP_UNREGISTER;
|
||||
arg.app_unreg.gatt_if = gatt_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 gatt_if, esp_bd_addr_t remote_bda, bool is_direct)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_OPEN;
|
||||
arg.open.gatt_if = gatt_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 (uint16_t conn_id)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_CLOSE;
|
||||
arg.close.conn_id = 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 (uint16_t conn_id, uint16_t mtu)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
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 = 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(uint16_t conn_id, esp_bt_uuid_t *filter_uuid)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_SEARCH_SERVICE;
|
||||
arg.search_srvc.conn_id = 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(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;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
if (start_char_id) {
|
||||
arg.get_next_char.conn_id = 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 = 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(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;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
|
||||
if (start_descr_id) {
|
||||
arg.get_next_descr.conn_id = 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 = 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(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;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
|
||||
if (start_incl_srvc_id) {
|
||||
arg.get_next_incl_srvc.conn_id = 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 = 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 (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;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_READ_CHAR;
|
||||
arg.read_char.conn_id = 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 (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;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_READ_CHAR_DESCR;
|
||||
arg.read_descr.conn_id = 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( 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;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_WRITE_CHAR;
|
||||
arg.write_char.conn_id = (uint16_t) 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 (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;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_WRITE_CHAR_DESCR;
|
||||
arg.write_descr.conn_id = (uint16_t) 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(uint16_t conn_id,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id,
|
||||
uint16_t offset,
|
||||
uint16_t value_len,
|
||||
uint8_t *value,
|
||||
esp_gatt_auth_req_t auth_req)
|
||||
{
|
||||
//TODO: Review this function
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_PREPARE_WRITE;
|
||||
arg.prep_write.conn_id = conn_id;
|
||||
memcpy(&arg.prep_write.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
|
||||
memcpy(&arg.prep_write.char_id, char_id, sizeof(esp_gatt_id_t));
|
||||
arg.prep_write.offset = offset;
|
||||
arg.prep_write.value_len = value_len > ESP_GATT_MAX_ATTR_LEN ? ESP_GATT_MAX_ATTR_LEN : value_len; // length check ?
|
||||
arg.prep_write.value = value;
|
||||
arg.prep_write.auth_req = auth_req;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), btc_gattc_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gattc_execute_write (uint16_t conn_id, bool is_execute)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gattc_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_EXECUTE_WRITE;
|
||||
arg.exec_write.conn_id = conn_id;
|
||||
arg.exec_write.is_execute = is_execute;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_gatt_status_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gatt_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;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_REG_FOR_NOTIFY;
|
||||
arg.reg_for_notify.gatt_if = gatt_if;
|
||||
memcpy(&arg.reg_for_notify.remote_bda, &server_bda, sizeof(esp_bd_addr_t));
|
||||
memcpy(&arg.reg_for_notify.service_id, srvc_id, sizeof(esp_gatt_srvc_id_t));
|
||||
memcpy(&arg.reg_for_notify.char_id, char_id, sizeof(esp_gatt_id_t));
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_gatt_status_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gatt_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;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTC;
|
||||
msg.act = BTC_GATTC_ACT_UNREG_FOR_NOTIFY;
|
||||
arg.unreg_for_notify.gatt_if = gatt_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);
|
||||
}
|
||||
|
||||
228
components/bt/bluedroid/api/esp_gatts_api.c
Normal file
228
components/bt/bluedroid/api/esp_gatts_api.c
Normal file
@@ -0,0 +1,228 @@
|
||||
// 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 "btc_manage.h"
|
||||
#include "btc_gatts.h"
|
||||
|
||||
#define COPY_TO_GATTS_ARGS(_gatt_args, _arg, _arg_type) memcpy(_gatt_args, _arg, sizeof(_arg_type))
|
||||
|
||||
esp_err_t esp_ble_gatts_register_callback(esp_profile_cb_t callback)
|
||||
{
|
||||
return (btc_profile_cb_set(BTC_PID_GATTS, callback) == 0 ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_gatts_app_register(uint16_t app_id)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
//if (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 gatt_if)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_APP_UNREGISTER;
|
||||
arg.app_unreg.gatt_if = gatt_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 gatt_if,
|
||||
esp_gatt_srvc_id_t *service_id, uint16_t num_handle)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_CREATE_SERVICE;
|
||||
arg.create_srvc.gatt_if = gatt_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_add_included_service(uint16_t service_handle, uint16_t included_service_handle)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_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)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_ADD_CHAR;
|
||||
arg.add_char.service_handle = service_handle;
|
||||
arg.add_char.perm = perm;
|
||||
arg.add_char.property = property;
|
||||
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), NULL) == 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)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_ADD_CHAR_DESCR;
|
||||
arg.add_descr.service_handle = service_handle;
|
||||
arg.add_descr.perm = perm;
|
||||
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), NULL) == 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;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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(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;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_SEND_INDICATE;
|
||||
arg.send_ind.conn_id = 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(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;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_SEND_RESPONSE;
|
||||
arg.send_rsp.conn_id = 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_open(esp_gatt_if_t gatt_if, esp_bd_addr_t remote_bda, bool is_direct)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_OPEN;
|
||||
arg.open.gatt_if = gatt_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(uint16_t conn_id)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
btc_ble_gatts_args_t arg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GATTS;
|
||||
msg.act = BTC_GATTS_ACT_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);
|
||||
}
|
||||
117
components/bt/bluedroid/api/include/esp_blufi_api.h
Normal file
117
components/bt/bluedroid/api/include/esp_blufi_api.h
Normal file
@@ -0,0 +1,117 @@
|
||||
// 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 "bt_types.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_gatt_defs.h"
|
||||
#include "bta_gatt_api.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#define ESP_BLUFI_RECV_DATA_LEN_MAX (64+1)
|
||||
|
||||
#define ESP_BLUFI_EVENT_INIT_FINISH 0
|
||||
#define ESP_BLUFI_EVENT_DEINIT_FINISH 1
|
||||
#define ESP_BLUFI_EVENT_RECV_DATA 2
|
||||
|
||||
/// BLUFI config status
|
||||
typedef enum {
|
||||
ESP_BLUFI_CONFIG_OK = 0,
|
||||
ESP_BLUFI_CONFIG_FAILED,
|
||||
} esp_blufi_config_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 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_RECV_DATA
|
||||
*/
|
||||
struct blufi_recv_evt_param {
|
||||
uint8_t data[ESP_BLUFI_RECV_DATA_LEN_MAX]; /*!< Blufi receive data */
|
||||
uint8_t data_len; /*!< Blufi receive data length */
|
||||
} recv_data; /*!< Blufi callback param of ESP_BLUFI_EVENT_RECV_DATA */
|
||||
} esp_blufi_cb_param_t;
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief This function is called to receive blufi callback event
|
||||
*
|
||||
* @param[in] callback: callback function
|
||||
*
|
||||
* @return ESP_OK - success, other - failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_blufi_register_callback(esp_profile_cb_t callback);
|
||||
|
||||
/**
|
||||
*
|
||||
* @brief This function is called to send config state to phone
|
||||
*
|
||||
* @param[in] state: blufi config OK or not
|
||||
*
|
||||
* @return ESP_OK - success, other - failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_blufi_send_config_state(esp_blufi_config_state_t state);
|
||||
|
||||
/**
|
||||
*
|
||||
* @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);
|
||||
|
||||
|
||||
|
||||
#endif /* _ESP_BLUFI_API_ */
|
||||
102
components/bt/bluedroid/api/include/esp_bt_defs.h
Normal file
102
components/bt/bluedroid/api/include/esp_bt_defs.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 __ESP_BT_DEFS_H__
|
||||
#define __ESP_BT_DEFS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/// Status Return Value
|
||||
typedef enum {
|
||||
ESP_BT_STATUS_SUCCESS = 0, /* Successful operation. */
|
||||
ESP_BT_STATUS_FAILURE = 1, /* Generic failure. */
|
||||
ESP_BT_STATUS_PENDING = 2, /* API cannot be completed right now */
|
||||
ESP_BT_STATUS_BUSY = 3,
|
||||
ESP_BT_STATUS_NO_RESOURCES = 4,
|
||||
ESP_BT_STATUS_WRONG_MODE = 5,
|
||||
} esp_bt_status_t;
|
||||
|
||||
/// Default GATT interface id
|
||||
#define ESP_DEFAULT_GATT_IF 0xff
|
||||
|
||||
/// Default BLE connection param, if the value doesn't be overwritten
|
||||
#define ESP_BLE_CONN_PARAM_UNDEF 0xffff /* use this value when a specific value not to be overwritten */
|
||||
|
||||
/// Check the param is valid or not
|
||||
#define ESP_BLE_IS_VALID_PARAM(x, min, max) (((x) >= (min) && (x) <= (max)) || ((x) == ESP_BLE_CONN_PARAM_UNDEF))
|
||||
|
||||
/// UUID type
|
||||
typedef struct {
|
||||
#define ESP_UUID_LEN_16 2
|
||||
#define ESP_UUID_LEN_32 4
|
||||
#define ESP_UUID_LEN_128 16
|
||||
uint16_t len; /*!< UUID length, 16bit, 32bit or 128bit */
|
||||
union {
|
||||
uint16_t uuid16;
|
||||
uint32_t uuid32;
|
||||
uint8_t uuid128[ESP_UUID_LEN_128];
|
||||
} uuid; /*!< UUID */
|
||||
} __attribute__((packed)) esp_bt_uuid_t;
|
||||
|
||||
/// Bluetooth device type
|
||||
typedef enum {
|
||||
ESP_BT_DEVICE_TYPE_BREDR = 0x01,
|
||||
ESP_BT_DEVICE_TYPE_BLE = 0x02,
|
||||
ESP_BT_DEVICE_TYPE_DUMO = 0x03,
|
||||
} esp_bt_dev_type_t;
|
||||
|
||||
/// Bluetooth address length
|
||||
#define ESP_BD_ADDR_LEN 6
|
||||
|
||||
/// Bluetooth device address
|
||||
typedef uint8_t esp_bd_addr_t[ESP_BD_ADDR_LEN];
|
||||
|
||||
/// Own BD address source of the device
|
||||
typedef enum {
|
||||
/// Public Address
|
||||
BD_ADDR_PUBLIC,
|
||||
/// Provided random address
|
||||
BD_ADDR_PROVIDED_RND,
|
||||
/// Provided static random address
|
||||
BD_ADDR_GEN_STATIC_RND,
|
||||
/// Generated resolvable private random address
|
||||
BD_ADDR_GEN_RSLV,
|
||||
/// Generated non-resolvable private random address
|
||||
BD_ADDR_GEN_NON_RSLV,
|
||||
/// Provided Reconnection address
|
||||
BD_ADDR_PROVIDED_RECON,
|
||||
} esp_bd_addr_type_t;
|
||||
|
||||
/// BLE device address type
|
||||
typedef enum {
|
||||
BLE_ADDR_TYPE_PUBLIC = 0x00,
|
||||
BLE_ADDR_TYPE_RANDOM = 0x01,
|
||||
BLE_ADDR_TYPE_RPA_PUBLIC = 0x02,
|
||||
BLE_ADDR_TYPE_RPA_RANDOM = 0x03,
|
||||
} esp_ble_addr_type_t;
|
||||
|
||||
/// Minimum of the application id
|
||||
#define ESP_APP_ID_MIN 0x0000
|
||||
/// Maximum of the application id
|
||||
#define ESP_APP_ID_MAX 0x7fff
|
||||
|
||||
/**
|
||||
* @brief Each profile callback function type
|
||||
* @param event : Event type
|
||||
* @param param : Point to callback parameter, currently is union type
|
||||
*/
|
||||
typedef void (* esp_profile_cb_t)(uint32_t event, void *param);
|
||||
|
||||
#endif ///__ESP_BT_DEFS_H__
|
||||
58
components/bt/bluedroid/api/include/esp_bt_main.h
Normal file
58
components/bt/bluedroid/api/include/esp_bt_main.h
Normal file
@@ -0,0 +1,58 @@
|
||||
// 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 "btc_main.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
/**
|
||||
* @brief Enable bluetooth, must after esp_init_bluetooth()
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Succeed
|
||||
* - Other : Failed
|
||||
*/
|
||||
esp_err_t esp_enable_bluetooth(void);
|
||||
|
||||
/**
|
||||
* @brief Disable bluetooth, must prior to esp_deinit_bluetooth()
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Succeed
|
||||
* - Other : Failed
|
||||
*/
|
||||
esp_err_t esp_disable_bluetooth(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_init_bluetooth(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_deinit_bluetooth(void);
|
||||
|
||||
|
||||
#endif /* __ESP_BT_MAIN_H__ */
|
||||
424
components/bt/bluedroid/api/include/esp_gap_ble_api.h
Normal file
424
components/bt/bluedroid/api/include/esp_gap_ble_api.h
Normal file
@@ -0,0 +1,424 @@
|
||||
// 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"
|
||||
|
||||
/// 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_cb_event_t;
|
||||
|
||||
/// Advertising data maximum length
|
||||
#define ESP_BLE_ADV_DATA_LEN_MAX 31
|
||||
|
||||
/// The type of advertising data(not adv_type)
|
||||
typedef enum {
|
||||
ESP_BLE_AD_TYPE_FLAG = 0x01,
|
||||
ESP_BLE_AD_TYPE_16SRV_PART = 0x02,
|
||||
ESP_BLE_AD_TYPE_16SRV_CMPL = 0x03,
|
||||
ESP_BLE_AD_TYPE_32SRV_PART = 0x04,
|
||||
ESP_BLE_AD_TYPE_32SRV_CMPL = 0x05,
|
||||
ESP_BLE_AD_TYPE_128SRV_PART = 0x06,
|
||||
ESP_BLE_AD_TYPE_128SRV_CMPL = 0x07,
|
||||
ESP_BLE_AD_TYPE_NAME_SHORT = 0x08,
|
||||
ESP_BLE_AD_TYPE_NAME_CMPL = 0x09,
|
||||
ESP_BLE_AD_TYPE_TX_PWR = 0x0A,
|
||||
ESP_BLE_AD_TYPE_DEV_CLASS = 0x0D,
|
||||
ESP_BLE_AD_TYPE_SM_TK = 0x10,
|
||||
ESP_BLE_AD_TYPE_SM_OOB_FLAG = 0x11,
|
||||
ESP_BLE_AD_TYPE_INT_RANGE = 0x12,
|
||||
ESP_BLE_AD_TYPE_SOL_SRV_UUID = 0x14,
|
||||
ESP_BLE_AD_TYPE_128SOL_SRV_UUID = 0x15,
|
||||
ESP_BLE_AD_TYPE_SERVICE_DATA = 0x16,
|
||||
ESP_BLE_AD_TYPE_PUBLIC_TARGET = 0x17,
|
||||
ESP_BLE_AD_TYPE_RANDOM_TARGET = 0x18,
|
||||
ESP_BLE_AD_TYPE_APPEARANCE = 0x19,
|
||||
ESP_BLE_AD_TYPE_ADV_INT = 0x1A,
|
||||
ESP_BLE_AD_TYPE_32SOL_SRV_UUID = 0x1B,
|
||||
ESP_BLE_AD_TYPE_32SERVICE_DATA = 0x1C,
|
||||
ESP_BLE_AD_TYPE_128SERVICE_DATA = 0x1D,
|
||||
ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE = 0xFF,
|
||||
} esp_ble_adv_data_type;
|
||||
|
||||
/// Advertising mode
|
||||
typedef enum {
|
||||
ADV_TYPE_IND = 0x00,
|
||||
ADV_TYPE_DIRECT_IND_HIGH = 0x01,
|
||||
ADV_TYPE_SCAN_IND = 0x02,
|
||||
ADV_TYPE_NONCONN_IND = 0x03,
|
||||
ADV_TYPE_DIRECT_IND_LOW = 0x04,
|
||||
} esp_ble_adv_type_t;
|
||||
|
||||
/// Advertising channel mask
|
||||
typedef enum {
|
||||
ADV_CHNL_37 = 0x01,
|
||||
ADV_CHNL_38 = 0x02,
|
||||
ADV_CHNL_39 = 0x03,
|
||||
ADV_CHNL_ALL = 0x07,
|
||||
} esp_ble_adv_channel_t;
|
||||
|
||||
typedef enum {
|
||||
///Allow both scan and connection requests from anyone
|
||||
ADV_FILTER_ALLOW_SCAN_ANY_CON_ANY = 0x00,
|
||||
///Allow both scan req from White List devices only and connection req from anyone
|
||||
ADV_FILTER_ALLOW_SCAN_WLST_CON_ANY,
|
||||
///Allow both scan req from anyone and connection req from White List devices only
|
||||
ADV_FILTER_ALLOW_SCAN_ANY_CON_WLST,
|
||||
///Allow scan and connection requests from White List devices only
|
||||
ADV_FILTER_ALLOW_SCAN_WLST_CON_WLST,
|
||||
///Enumeration end value for advertising filter policy value check
|
||||
} esp_ble_adv_filter_t;
|
||||
|
||||
/// Advertising parameters
|
||||
typedef struct {
|
||||
uint16_t adv_int_min; /*!< Minimum advertising interval for
|
||||
undirected and low duty cycle directed advertising.
|
||||
Range: 0x0020 to 0x4000 Default: N = 0x0800 (1.28 second)
|
||||
Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec */
|
||||
uint16_t adv_int_max; /*!< Maximum advertising interval for
|
||||
undirected and low duty cycle directed advertising.
|
||||
Range: 0x0020 to 0x4000 Default: N = 0x0800 (1.28 second)
|
||||
Time = N * 0.625 msec Time Range: 20 ms to 10.24 sec Advertising max interval */
|
||||
esp_ble_adv_type_t adv_type; /*!< Advertising type */
|
||||
esp_ble_addr_type_t own_addr_type; /*!< Owner bluetooth device address type */
|
||||
esp_bd_addr_t peer_addr; /*!< Peer device bluetooth device address */
|
||||
esp_ble_addr_type_t peer_addr_type; /*!< Peer device bluetooth device address type */
|
||||
esp_ble_adv_channel_t channel_map; /*!< Advertising channel map */
|
||||
esp_ble_adv_filter_t adv_filter_policy; /*!< Advertising filter policy */
|
||||
} esp_ble_adv_params_t;
|
||||
|
||||
/// Advertising data content, according to "Supplement to the Bluetooth Core Specification"
|
||||
typedef struct {
|
||||
bool set_scan_rsp; /*!< Set this advertising data as scan response or not*/
|
||||
bool include_name; /*!< Advertising data include device name or not */
|
||||
bool include_txpower; /*!< Advertising data include TX power */
|
||||
int min_interval; /*!< Advertising data show advertising min interval */
|
||||
int max_interval; /*!< Advertising data show advertising max interval */
|
||||
int appearance; /*!< External appearance of device */
|
||||
uint16_t manufacturer_len; /*!< Manufacturer data length */
|
||||
uint8_t *p_manufacturer_data; /*!< Manufacturer data point */
|
||||
uint16_t service_data_len; /*!< Service data length */
|
||||
uint8_t *p_service_data; /*!< Service data point */
|
||||
uint16_t service_uuid_len; /*!< Service uuid length */
|
||||
uint8_t *p_service_uuid; /*!< Service uuid array point */
|
||||
uint8_t flag; /*!< Advertising flag of discovery mode */
|
||||
} esp_ble_adv_data_t;
|
||||
|
||||
/// Own BD address source of the device
|
||||
typedef enum {
|
||||
/// Public Address
|
||||
ESP_PUBLIC_ADDR,
|
||||
/// Provided random address
|
||||
ESP_PROVIDED_RND_ADDR,
|
||||
/// Provided static random address
|
||||
ESP_GEN_STATIC_RND_ADDR,
|
||||
/// Generated resolvable private random address
|
||||
ESP_GEN_RSLV_ADDR,
|
||||
/// Generated non-resolvable private random address
|
||||
ESP_GEN_NON_RSLV_ADDR,
|
||||
/// Provided Reconnection address
|
||||
ESP_PROVIDED_RECON_ADDR,
|
||||
} esp_ble_own_addr_src_t;
|
||||
|
||||
/// Ble scan type
|
||||
typedef enum {
|
||||
BLE_SCAN_TYPE_PASSIVE = 0x0, /*!< Passive scan */
|
||||
BLE_SCAN_TYPE_ACTIVE = 0x1, /*!< Active scan */
|
||||
} esp_ble_scan_type_t;
|
||||
|
||||
/// Ble scan filter type
|
||||
typedef enum {
|
||||
BLE_SCAN_FILTER_ALLOW_ALL = 0x0, /*!< Accept all :
|
||||
1. advertisement packets except directed advertising packets not addressed to this device (default). */
|
||||
BLE_SCAN_FILTER_ALLOW_ONLY_WLST = 0x1, /*!< Accept only :
|
||||
1. advertisement packets from devices where the advertiser’s address is in the White list.
|
||||
2. Directed advertising packets which are not addressed for this device shall be ignored. */
|
||||
BLE_SCAN_FILTER_ALLOW_UND_RPA_DIR = 0x2, /*!< Accept all :
|
||||
1. undirected advertisement packets, and
|
||||
2. directed advertising packets where the initiator address is a resolvable private address, and
|
||||
3. directed advertising packets addressed to this device. */
|
||||
BLE_SCAN_FILTER_ALLOW_WLIST_PRA_DIR = 0x3, /*!< Accept all :
|
||||
1. advertisement packets from devices where the advertiser’s address is in the White list, and
|
||||
2. directed advertising packets where the initiator address is a resolvable private address, and
|
||||
3. directed advertising packets addressed to this device.*/
|
||||
} esp_ble_scan_filter_t;
|
||||
|
||||
/// Ble scan parameters
|
||||
typedef struct {
|
||||
esp_ble_scan_type_t scan_type; /*!< Scan type */
|
||||
esp_ble_addr_type_t own_addr_type; /*!< Owner address type */
|
||||
esp_ble_scan_filter_t scan_filter_policy; /*!< Scan filter policy */
|
||||
uint16_t scan_interval; /*!< Scan interval. This is defined as the time interval from
|
||||
when the Controller started its last LE scan until it begins the subsequent LE scan.
|
||||
Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
|
||||
Time = N * 0.625 msec
|
||||
Time Range: 2.5 msec to 10.24 seconds*/
|
||||
uint16_t scan_window; /*!< Scan window. The duration of the LE scan. LE_Scan_Window
|
||||
shall be less than or equal to LE_Scan_Interval
|
||||
Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
|
||||
Time = N * 0.625 msec
|
||||
Time Range: 2.5 msec to 10240 msec */
|
||||
} esp_ble_scan_params_t;
|
||||
|
||||
/// Connection update parameters
|
||||
typedef struct {
|
||||
esp_bd_addr_t bda; /*!< Bluetooth device address */
|
||||
uint16_t min_int; /*!< Min connection interval */
|
||||
uint16_t max_int; /*!< Max connection interval */
|
||||
uint16_t latency; /*!< Slave latency for the connection in number of connection events. Range: 0x0000 to 0x01F3 */
|
||||
uint16_t timeout; /*!< Supervision timeout for the LE Link. Range: 0x000A to 0x0C80.
|
||||
Mandatory Range: 0x000A to 0x0C80 Time = N * 10 msec
|
||||
Time Range: 100 msec to 32 seconds */
|
||||
} esp_ble_conn_update_params_t;
|
||||
|
||||
/// Sub Event of ESP_GAP_BLE_SCAN_RESULT_EVT
|
||||
typedef enum {
|
||||
ESP_GAP_SEARCH_INQ_RES_EVT = 0, /*!< Inquiry result for a peer device. */
|
||||
ESP_GAP_SEARCH_INQ_CMPL_EVT = 1, /*!< Inquiry complete. */
|
||||
ESP_GAP_SEARCH_DISC_RES_EVT = 2, /*!< Discovery result for a peer device. */
|
||||
ESP_GAP_SEARCH_DISC_BLE_RES_EVT = 3, /*!< Discovery result for BLE GATT based service on a peer device. */
|
||||
ESP_GAP_SEARCH_DISC_CMPL_EVT = 4, /*!< Discovery complete. */
|
||||
ESP_GAP_SEARCH_DI_DISC_CMPL_EVT = 5, /*!< Discovery complete. */
|
||||
ESP_GAP_SEARCH_SEARCH_CANCEL_CMPL_EVT = 6, /*!< Search cancelled */
|
||||
} esp_gap_search_evt_t;
|
||||
|
||||
/**
|
||||
* @brief Ble scan result event type, to indicate the
|
||||
* result is scan response or advertising data or other
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_BLE_EVT_CONN_ADV = 0x00, /*!< Connectable undirected advertising (ADV_IND) */
|
||||
ESP_BLE_EVT_CONN_DIR_ADV = 0x01, /*!< Connectable directed advertising (ADV_DIRECT_IND) */
|
||||
ESP_BLE_EVT_DISC_ADV = 0x02, /*!< Scannable undirected advertising (ADV_SCAN_IND) */
|
||||
ESP_BLE_EVT_NON_CONN_ADV = 0x03, /*!< Non connectable undirected advertising (ADV_NONCONN_IND) */
|
||||
ESP_BLE_EVT_SCAN_RSP = 0x04, /*!< Scan Response (SCAN_RSP) */
|
||||
} esp_ble_evt_type_t;
|
||||
|
||||
/**
|
||||
* @brief Gap callback parameters union
|
||||
*/
|
||||
typedef union {
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT
|
||||
*/
|
||||
struct ble_adv_data_cmpl_evt_param {
|
||||
esp_bt_status_t status; /*!< Indicate the set advertising data operation success status */
|
||||
} adv_data_cmpl; /*!< Event parameter of ESP_GAP_BLE_ADV_DATA_SET_COMPLETE_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT
|
||||
*/
|
||||
struct ble_scan_rsp_data_cmpl_evt_param {
|
||||
esp_bt_status_t status; /*!< Indicate the set scan response data operation success status */
|
||||
} scan_rsp_data_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_RSP_DATA_SET_COMPLETE_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT
|
||||
*/
|
||||
struct ble_scan_param_cmpl_evt_param {
|
||||
esp_bt_status_t status; /*!< Indicate the set scan param operation success status */
|
||||
} scan_param_cmpl; /*!< Event parameter of ESP_GAP_BLE_SCAN_PARAM_SET_COMPLETE_EVT */
|
||||
/**
|
||||
* @brief ESP_GAP_BLE_SCAN_RESULT_EVT
|
||||
*/
|
||||
struct ble_scan_result_evt_param {
|
||||
esp_gap_search_evt_t search_evt; /*!< Search event type */
|
||||
esp_bd_addr_t bda; /*!< Bluetooth device address which has been searched */
|
||||
esp_bt_dev_type_t dev_type; /*!< Device type */
|
||||
esp_ble_addr_type_t ble_addr_type; /*!< Ble device address type */
|
||||
esp_ble_evt_type_t ble_evt_type; /*!< Ble scan result event type */
|
||||
int rssi; /*!< Searched device's RSSI */
|
||||
uint8_t ble_adv[ESP_BLE_ADV_DATA_LEN_MAX]; /*!< Received EIR */
|
||||
int flag; /*!< Advertising data flag bit */
|
||||
int num_resps; /*!< Scan result number */
|
||||
} scan_rst; /*!< Event parameter of ESP_GAP_BLE_SCAN_RESULT_EVT */
|
||||
} esp_ble_gap_cb_param_t;
|
||||
|
||||
/**
|
||||
* @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_profile_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 pointer of ADV data
|
||||
*
|
||||
*/
|
||||
uint8_t *esp_ble_resolve_adv_data(uint8_t *adv_data, uint8_t type, uint8_t *length);
|
||||
|
||||
#endif /* __ESP_GAP_BLE_API_H__ */
|
||||
177
components/bt/bluedroid/api/include/esp_gatt_defs.h
Normal file
177
components/bt/bluedroid/api/include/esp_gatt_defs.h
Normal file
@@ -0,0 +1,177 @@
|
||||
// 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"
|
||||
|
||||
/// Attribute write data type from the client
|
||||
typedef enum {
|
||||
ESP_GATT_PREP_WRITE_CANCEL = 0x00, /*!< Prepare write cancel */
|
||||
ESP_GATT_PREP_WRITE_EXEC = 0x01, /*!< Prepare write execute */
|
||||
} esp_gatt_prep_write_type;
|
||||
|
||||
/**
|
||||
* @brief GATT success code and error codes
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_GATT_OK = 0x0,
|
||||
ESP_GATT_INVALID_HANDLE = 0x01, /* 0x0001 */
|
||||
ESP_GATT_READ_NOT_PERMIT = 0x02, /* 0x0002 */
|
||||
ESP_GATT_WRITE_NOT_PERMIT = 0x03, /* 0x0003 */
|
||||
ESP_GATT_INVALID_PDU = 0x04, /* 0x0004 */
|
||||
ESP_GATT_INSUF_AUTHENTICATION = 0x05, /* 0x0005 */
|
||||
ESP_GATT_REQ_NOT_SUPPORTED = 0x06, /* 0x0006 */
|
||||
ESP_GATT_INVALID_OFFSET = 0x07, /* 0x0007 */
|
||||
ESP_GATT_INSUF_AUTHORIZATION = 0x08, /* 0x0008 */
|
||||
ESP_GATT_PREPARE_Q_FULL = 0x09, /* 0x0009 */
|
||||
ESP_GATT_NOT_FOUND = 0x0a, /* 0x000a */
|
||||
ESP_GATT_NOT_LONG = 0x0b, /* 0x000b */
|
||||
ESP_GATT_INSUF_KEY_SIZE = 0x0c, /* 0x000c */
|
||||
ESP_GATT_INVALID_ATTR_LEN = 0x0d, /* 0x000d */
|
||||
ESP_GATT_ERR_UNLIKELY = 0x0e, /* 0x000e */
|
||||
ESP_GATT_INSUF_ENCRYPTION = 0x0f, /* 0x000f */
|
||||
ESP_GATT_UNSUPPORT_GRP_TYPE = 0x10, /* 0x0010 */
|
||||
ESP_GATT_INSUF_RESOURCE = 0x11, /* 0x0011 */
|
||||
|
||||
ESP_GATT_NO_RESOURCES = 0x80, /* 0x80 */
|
||||
ESP_GATT_INTERNAL_ERROR = 0x81, /* 0x81 */
|
||||
ESP_GATT_WRONG_STATE = 0x82, /* 0x82 */
|
||||
ESP_GATT_DB_FULL = 0x83, /* 0x83 */
|
||||
ESP_GATT_BUSY = 0x84, /* 0x84 */
|
||||
ESP_GATT_ERROR = 0x85, /* 0x85 */
|
||||
ESP_GATT_CMD_STARTED = 0x86, /* 0x86 */
|
||||
ESP_GATT_ILLEGAL_PARAMETER = 0x87, /* 0x87 */
|
||||
ESP_GATT_PENDING = 0x88, /* 0x88 */
|
||||
ESP_GATT_AUTH_FAIL = 0x89, /* 0x89 */
|
||||
ESP_GATT_MORE = 0x8a, /* 0x8a */
|
||||
ESP_GATT_INVALID_CFG = 0x8b, /* 0x8b */
|
||||
ESP_GATT_SERVICE_STARTED = 0x8c, /* 0x8c */
|
||||
ESP_GATT_ENCRYPED_MITM = ESP_GATT_OK,
|
||||
ESP_GATT_ENCRYPED_NO_MITM = 0x8d, /* 0x8d */
|
||||
ESP_GATT_NOT_ENCRYPTED = 0x8e, /* 0x8e */
|
||||
ESP_GATT_CONGESTED = 0x8f, /* 0x8f */
|
||||
ESP_GATT_DUP_REG = 0x90, /* 0x90 */
|
||||
ESP_GATT_ALREADY_OPEN = 0x91, /* 0x91 */
|
||||
ESP_GATT_CANCEL = 0x92, /* 0x92 */
|
||||
|
||||
/* 0xE0 ~ 0xFC reserved for future use */
|
||||
ESP_GATT_CCC_CFG_ERR = 0xfd, /* 0xFD Client Characteristic Configuration Descriptor Improperly Configured */
|
||||
ESP_GATT_PRC_IN_PROGRESS = 0xfe, /* 0xFE Procedure Already in progress */
|
||||
ESP_GATT_OUT_OF_RANGE = 0xff, /* 0xFFAttribute value out of range */
|
||||
} esp_gatt_status_t;
|
||||
|
||||
/**
|
||||
* @brief Gatt Connection reason enum
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_GATT_CONN_UNKNOWN = 0, /*!< Gatt connection unknown */
|
||||
ESP_GATT_CONN_L2C_FAILURE = 1, /*!< General L2cap failure */
|
||||
ESP_GATT_CONN_TIMEOUT = 0x08, /*!< Connection timeout */
|
||||
ESP_GATT_CONN_TERMINATE_PEER_USER = 0x13, /*!< Connection terminate by peer user */
|
||||
ESP_GATT_CONN_TERMINATE_LOCAL_HOST = 0x16, /*!< Connectionterminated by local host */
|
||||
ESP_GATT_CONN_FAIL_ESTABLISH = 0x3e, /*!< Connection fail to establish */
|
||||
ESP_GATT_CONN_LMP_TIMEOUT = 0x22, /*!< Connection fail for LMP response tout */
|
||||
ESP_GATT_CONN_CONN_CANCEL = 0x0100, /*!< L2CAP connection cancelled */
|
||||
ESP_GATT_CONN_NONE = 0x0101 /*!< No connection to cancel */
|
||||
} esp_gatt_conn_reason_t;
|
||||
|
||||
/**
|
||||
* @brief Gatt id, include uuid and instance id
|
||||
*/
|
||||
typedef struct {
|
||||
esp_bt_uuid_t uuid; /*!< UUID */
|
||||
uint8_t inst_id; /*!< Instance id */
|
||||
} __attribute__((packed)) esp_gatt_id_t;
|
||||
|
||||
/**
|
||||
* @brief Gatt service id, include id
|
||||
* (uuid and instance id) and primary flag
|
||||
*/
|
||||
typedef struct {
|
||||
esp_gatt_id_t id; /*!< Gatt id, include uuid and instance */
|
||||
bool is_primary; /*!< This service is primary or not */
|
||||
} __attribute__((packed)) esp_gatt_srvc_id_t;
|
||||
|
||||
/**
|
||||
* @brief Gatt authentication request type
|
||||
*/
|
||||
typedef enum {
|
||||
AUTH_REQ_NO_SCATTERNET, /* Device doesn't support scatternet, it might
|
||||
support "role switch during connection" for
|
||||
an incoming connection, when it already has
|
||||
another connection in master role */
|
||||
AUTH_REQ_PARTIAL_SCATTERNET, /* Device supports partial scatternet. It can have
|
||||
simulateous connection in Master and Slave roles
|
||||
for short period of time */
|
||||
AUTH_REQ_FULL_SCATTERNET /* Device can have simultaneous connection in master
|
||||
and slave roles */
|
||||
} esp_gatt_auth_req_t;
|
||||
|
||||
/**
|
||||
* @brief Attribute permissions
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_GATT_PERM_READ = (1 << 0), /* bit 0 - 0x0001 */
|
||||
ESP_GATT_PERM_READ_ENCRYPTED = (1 << 1), /* bit 1 - 0x0002 */
|
||||
ESP_GATT_PERM_READ_ENC_MITM = (1 << 2), /* bit 2 - 0x0004 */
|
||||
ESP_GATT_PERM_WRITE = (1 << 4), /* bit 4 - 0x0010 */
|
||||
ESP_GATT_PERM_WRITE_ENCRYPTED = (1 << 5), /* bit 5 - 0x0020 */
|
||||
ESP_GATT_PERM_WRITE_ENC_MITM = (1 << 6), /* bit 6 - 0x0040 */
|
||||
ESP_GATT_PERM_WRITE_SIGNED = (1 << 7), /* bit 7 - 0x0080 */
|
||||
ESP_GATT_PERM_WRITE_SIGNED_MITM = (1 << 8), /* bit 8 - 0x0100 */
|
||||
} esp_gatt_perm_t;
|
||||
|
||||
/* definition of characteristic properties */
|
||||
typedef enum {
|
||||
ESP_GATT_CHAR_PROP_BIT_BROADCAST = (1 << 0), /* 0x01 */
|
||||
ESP_GATT_CHAR_PROP_BIT_READ = (1 << 1), /* 0x02 */
|
||||
ESP_GATT_CHAR_PROP_BIT_WRITE_NR = (1 << 2), /* 0x04 */
|
||||
ESP_GATT_CHAR_PROP_BIT_WRITE = (1 << 3), /* 0x08 */
|
||||
ESP_GATT_CHAR_PROP_BIT_NOTIFY = (1 << 4), /* 0x10 */
|
||||
ESP_GATT_CHAR_PROP_BIT_INDICATE = (1 << 5), /* 0x20 */
|
||||
ESP_GATT_CHAR_PROP_BIT_AUTH = (1 << 6), /* 0x40 */
|
||||
ESP_GATT_CHAR_PROP_BIT_EXT_PROP = (1 << 7), /* 0x80 */
|
||||
} esp_gatt_char_prop_t;
|
||||
|
||||
/// GATT maximum attribute length
|
||||
#define ESP_GATT_MAX_ATTR_LEN 600 //as same as GATT_MAX_ATTR_LEN
|
||||
|
||||
/// 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;
|
||||
|
||||
typedef uint32_t esp_gatt_if_t; /*!< Gatt interface type, different application on GATT client use different gatt_if */
|
||||
|
||||
#endif /* __ESP_GATT_DEFS_H__ */
|
||||
576
components/bt/bluedroid/api/include/esp_gattc_api.h
Executable file
576
components/bt/bluedroid/api/include/esp_gattc_api.h
Executable file
@@ -0,0 +1,576 @@
|
||||
// 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 "bt_types.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_gatt_defs.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
/// GATT Client callback function events
|
||||
typedef enum {
|
||||
ESP_GATTC_REG_EVT = 0, /*!< When GATT client is registered, the event comes */
|
||||
ESP_GATTC_UNREG_EVT = 1, /*!< When GATT client is unregistered, the event comes */
|
||||
ESP_GATTC_OPEN_EVT = 2, /*!< When GATT connection is set up, the event comes */
|
||||
ESP_GATTC_READ_CHAR_EVT = 3, /*!< When GATT characteristic is read, the event comes */
|
||||
ESP_GATTC_WRITE_CHAR_EVT = 4, /*!< When GATT characteristic write operation completes, the event comes */
|
||||
ESP_GATTC_CLOSE_EVT = 5, /*!< When GATT connection is closed, the event comes */
|
||||
ESP_GATTC_SEARCH_CMPL_EVT = 6, /*!< When GATT service discovery is completed, the event comes */
|
||||
ESP_GATTC_SEARCH_RES_EVT = 7, /*!< When GATT service discovery result is got, the event comes */
|
||||
ESP_GATTC_READ_DESCR_EVT = 8, /*!< When GATT characteristic descriptor read completes, the event comes */
|
||||
ESP_GATTC_WRITE_DESCR_EVT = 9, /*!< When GATT characteristic descriptor write completes, the event comes */
|
||||
ESP_GATTC_NOTIFY_EVT = 10, /*!< When GATT notification or indication arrives, the event comes */
|
||||
ESP_GATTC_PREP_WRITE_EVT = 11, /*!< When GATT prepare-write operation completes, the event comes */
|
||||
ESP_GATTC_EXEC_EVT = 12, /*!< When write execution completes, the event comes */
|
||||
ESP_GATTC_ACL_EVT = 13, /*!< When ACL connection is up, the event comes */
|
||||
ESP_GATTC_CANCEL_OPEN_EVT = 14, /*!< When GATT client ongoing connection is cancelled, the event comes */
|
||||
ESP_GATTC_SRVC_CHG_EVT = 15, /*!< When "service changed" occurs, the event comes */
|
||||
ESP_GATTC_ENC_CMPL_CB_EVT = 17, /*!< When encryption procedure completes, the event comes */
|
||||
ESP_GATTC_CFG_MTU_EVT = 18, /*!< When configuration of MTU completes, the event comes */
|
||||
ESP_GATTC_ADV_DATA_EVT = 19, /*!< When advertising of data, the event comes */
|
||||
ESP_GATTC_MULT_ADV_ENB_EVT = 20, /*!< When multi-advertising is enabled, the event comes */
|
||||
ESP_GATTC_MULT_ADV_UPD_EVT = 21, /*!< When multi-advertising parameters are updated, the event comes */
|
||||
ESP_GATTC_MULT_ADV_DATA_EVT = 22, /*!< When multi-advertising data arrives, the event comes */
|
||||
ESP_GATTC_MULT_ADV_DIS_EVT = 23, /*!< When multi-advertising is disabled, the event comes */
|
||||
ESP_GATTC_CONGEST_EVT = 24, /*!< When GATT connection congestion comes, the event comes */
|
||||
ESP_GATTC_BTH_SCAN_ENB_EVT = 25, /*!< When batch scan is enabled, the event comes */
|
||||
ESP_GATTC_BTH_SCAN_CFG_EVT = 26, /*!< When batch scan storage is configured, the event comes */
|
||||
ESP_GATTC_BTH_SCAN_RD_EVT = 27, /*!< When Batch scan read event is reported, the event comes */
|
||||
ESP_GATTC_BTH_SCAN_THR_EVT = 28, /*!< When Batch scan threshold is set, the event comes */
|
||||
ESP_GATTC_BTH_SCAN_PARAM_EVT = 29, /*!< When Batch scan parameters are set, the event comes */
|
||||
ESP_GATTC_BTH_SCAN_DIS_EVT = 30, /*!< When Batch scan is disabled, the event comes */
|
||||
ESP_GATTC_SCAN_FLT_CFG_EVT = 31, /*!< When Scan filter configuration completes, the event comes */
|
||||
ESP_GATTC_SCAN_FLT_PARAM_EVT = 32, /*!< When Scan filter parameters are set, the event comes */
|
||||
ESP_GATTC_SCAN_FLT_STATUS_EVT = 33, /*!< When Scan filter status is reported, the event comes */
|
||||
ESP_GATTC_ADV_VSC_EVT = 34, /*!< When advertising vendor spec content event is reported, the event comes */
|
||||
ESP_GATTC_GET_CHAR_EVT = 35, /*!< When characteristic is got from GATT server, the event comes */
|
||||
ESP_GATTC_GET_DESCR_EVT = 36, /*!< When characteristic descriptor is got from GATT server, the event comes */
|
||||
ESP_GATTC_GET_INCL_SRVC_EVT = 37, /*!< When included service is got from GATT server, the event comes */
|
||||
ESP_GATTC_REG_FOR_NOTIFY_EVT = 38, /*!< When register for notification of a service completes, the event comes */
|
||||
ESP_GATTC_UNREG_FOR_NOTIFY_EVT = 39, /*!< When unregister for notification of a service completes, the event comes */
|
||||
} esp_gattc_cb_event_t;
|
||||
|
||||
/// Maximum Transmission Unit used in GATT
|
||||
#define ESP_GATT_DEF_BLE_MTU_SIZE 23
|
||||
|
||||
/// Maximum Transmission Unit allowed in GATT
|
||||
#define ESP_GATT_MAX_MTU_SIZE 517
|
||||
|
||||
/**
|
||||
* @brief Gatt client callback parameters union
|
||||
*/
|
||||
typedef union {
|
||||
/**
|
||||
* @brief ESP_GATTC_REG_EVT
|
||||
*/
|
||||
struct gattc_reg_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
esp_gatt_if_t gatt_if; /*!< Gatt interface id, different application on gatt client different gatt_if */
|
||||
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_gatt_if_t gatt_if; /*!< Gatt interface id, different application on gatt client different gatt_if */
|
||||
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_gatt_if_t gatt_if; /*!< Gatt interface id, different application on gatt client different gatt_if */
|
||||
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
|
||||
esp_gatt_conn_reason_t reason; /*!< The reason of gatt connection close */
|
||||
} close; /*!< Gatt client callback param of ESP_GATTC_CLOSE_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_CFG_MTU_EVT
|
||||
*/
|
||||
struct gattc_cfg_mtu_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
uint16_t mtu; /*!< MTU size */
|
||||
} cfg_mtu; /*!< Gatt client callback param of ESP_GATTC_CFG_MTU_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_SEARCH_CMPL_EVT
|
||||
*/
|
||||
struct gattc_search_cmpl_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
} search_cmpl; /*!< Gatt client callback param of ESP_GATTC_SEARCH_CMPL_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_SEARCH_RES_EVT
|
||||
*/
|
||||
struct gattc_search_res_evt_param {
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
|
||||
} search_res; /*!< Gatt client callback param of ESP_GATTC_SEARCH_RES_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_READ_CHAR_EVT, ESP_GATTC_READ_DESCR_EVT
|
||||
*/
|
||||
struct gattc_read_char_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
|
||||
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
|
||||
esp_gatt_id_t descr_id; /*!< Descriptor id, include descriptor uuid and other information */
|
||||
uint8_t *value; /*!< Characteristic value */
|
||||
uint16_t value_type; /*!< Characteristic value type */
|
||||
uint16_t value_len; /*!< Characteristic value length */
|
||||
} read; /*!< Gatt client callback param of ESP_GATTC_READ_CHAR_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_WRITE_CHAR_EVT, ESP_GATTC_PREP_WRITE_EVT, ESP_GATTC_WRITE_DESCR_EVT
|
||||
*/
|
||||
struct gattc_write_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
|
||||
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
|
||||
esp_gatt_id_t descr_id; /*!< Descriptor id, include descriptor uuid and other information */
|
||||
} write; /*!< Gatt client callback param of ESP_GATTC_WRITE_DESCR_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_EXEC_EVT
|
||||
*/
|
||||
struct gattc_exec_cmpl_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
} exec_cmpl; /*!< Gatt client callback param of ESP_GATTC_EXEC_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_NOTIFY_EVT
|
||||
*/
|
||||
struct gattc_notify_evt_param {
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
|
||||
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
|
||||
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
|
||||
esp_gatt_id_t descr_id; /*!< Descriptor id, include descriptor uuid and other information */
|
||||
uint16_t value_len; /*!< Notify attribute value */
|
||||
uint8_t *value; /*!< Notify attribute value */
|
||||
bool is_notify; /*!< True means notify, false means indicate */
|
||||
} notify; /*!< Gatt client callback param of ESP_GATTC_NOTIFY_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_SRVC_CHG_EVT
|
||||
*/
|
||||
struct gattc_srvc_chg_evt_param {
|
||||
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
|
||||
} srvc_chg; /*!< Gatt client callback param of ESP_GATTC_SRVC_CHG_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_CONGEST_EVT
|
||||
*/
|
||||
struct gattc_congest_evt_param {
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
bool congested; /*!< Congested or not */
|
||||
} congest; /*!< Gatt client callback param of ESP_GATTC_CONGEST_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_GET_CHAR_EVT
|
||||
*/
|
||||
struct gattc_get_char_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
|
||||
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
|
||||
esp_gatt_char_prop_t char_prop; /*!< Characteristic property */
|
||||
} get_char; /*!< Gatt client callback param of ESP_GATTC_GET_CHAR_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_GET_DESCR_EVT
|
||||
*/
|
||||
struct gattc_get_descr_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
|
||||
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
|
||||
esp_gatt_id_t descr_id; /*!< Descriptor id, include descriptor uuid and other information */
|
||||
} get_descr; /*!< Gatt client callback param of ESP_GATTC_GET_DESCR_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_GET_INCL_SRVC_EVT
|
||||
*/
|
||||
struct gattc_get_incl_srvc_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
|
||||
esp_gatt_srvc_id_t incl_srvc_id;/*!< Included service id, include service uuid and other information */
|
||||
} get_incl_srvc; /*!< Gatt client callback param of ESP_GATTC_GET_INCL_SRVC_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_REG_FOR_NOTIFY_EVT
|
||||
*/
|
||||
struct gattc_reg_for_notify_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
|
||||
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
|
||||
} reg_for_notify; /*!< Gatt client callback param of ESP_GATTC_REG_FOR_NOTIFY_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTC_UNREG_FOR_NOTIFY_EVT
|
||||
*/
|
||||
struct gattc_unreg_for_notify_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
esp_gatt_srvc_id_t srvc_id; /*!< Service id, include service uuid and other information */
|
||||
esp_gatt_id_t char_id; /*!< Characteristic id, include characteristic uuid and other information */
|
||||
} unreg_for_notify; /*!< Gatt client callback param of ESP_GATTC_UNREG_FOR_NOTIFY_EVT */
|
||||
|
||||
|
||||
} esp_ble_gattc_cb_param_t; /*!< GATT client callback parameter union type */
|
||||
|
||||
|
||||
/**
|
||||
* @brief 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_profile_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] gatt_if : app identifier.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gattc_app_unregister(esp_gatt_if_t gatt_if);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Open a direct connection or add a background auto connection
|
||||
*
|
||||
* @param[in] gatt_if: application identity.
|
||||
* @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 gatt_if, esp_bd_addr_t remote_bda, bool is_direct);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Close a connection to a GATT server.
|
||||
*
|
||||
* @param[in] conn_id: connection ID to be closed.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gattc_close(uint16_t conn_id);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Configure the MTU size in the GATT channel. This can be done
|
||||
* only once per connection.
|
||||
*
|
||||
* @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(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] 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(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] 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(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] 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(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] 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(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 characteriistic ID
|
||||
*
|
||||
* @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 (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] 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 (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] 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( 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] 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 (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] 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(uint16_t conn_id,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id,
|
||||
uint16_t offset,
|
||||
uint16_t value_len,
|
||||
uint8_t *value,
|
||||
esp_gatt_auth_req_t auth_req);
|
||||
|
||||
/**
|
||||
* @brief This function is called to execute write a prepare write sequence.
|
||||
*
|
||||
* @param[in] 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 (uint16_t conn_id, bool is_execute);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function is called to register for notification of a service.
|
||||
*
|
||||
* @param[in] gatt_if : gatt interface id.
|
||||
* @param[in] server_bda : target GATT server.
|
||||
* @param[in] srvc_id : pointer to GATT service ID.
|
||||
* @param[in] char_id : pointer to GATT characteristic ID.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: registration succeeds
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_gatt_status_t esp_ble_gattc_register_for_notify (esp_gatt_if_t gatt_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] gatt_if : gatt interface id.
|
||||
* @param[in] server_bda : target GATT server.
|
||||
* @param[in] srvc_id : pointer to GATT service ID.
|
||||
* @param[in] char_id : pointer to GATT characteristic ID.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: unregister succeeds
|
||||
* - other: failed
|
||||
*
|
||||
*/
|
||||
esp_gatt_status_t esp_ble_gattc_unregister_for_notify (esp_gatt_if_t gatt_if,
|
||||
esp_bd_addr_t server_bda,
|
||||
esp_gatt_srvc_id_t *srvc_id,
|
||||
esp_gatt_id_t *char_id);
|
||||
|
||||
|
||||
#endif /* __ESP_GATTC_API_H__ */
|
||||
462
components/bt/bluedroid/api/include/esp_gatts_api.h
Normal file
462
components/bt/bluedroid/api/include/esp_gatts_api.h
Normal file
@@ -0,0 +1,462 @@
|
||||
// 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 "bt_types.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_gatt_defs.h"
|
||||
#include "bta_gatt_api.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
/// 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_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 gatt_if; /*!< Gatt interface id, different application on gatt client different gatt_if */
|
||||
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 */
|
||||
} 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
|
||||
#define ESP_GATT_PREP_WRITE_EXEC 0x01
|
||||
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 gatt_if; /*!< Gatt interface id, different application on gatt client different gatt_if */
|
||||
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 gatt_if; /*!< Gatt interface id, different application on gatt client different gatt_if */
|
||||
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 gatt_if; /*!< Gatt interface id, different application on gatt client different gatt_if */
|
||||
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 gatt_if; /*!< Gatt interface id, different application on gatt client different gatt_if */
|
||||
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 gatt_if; /*!< Gatt interface id, different application on gatt client different gatt_if */
|
||||
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 gatt_if; /*!< Gatt interface id, different application on gatt client different gatt_if */
|
||||
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 gatt_if; /*!< Gatt interface id, different application on gatt client different gatt_if */
|
||||
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 */
|
||||
uint16_t gatt_if; /*!< Gatt interface id, different application on gatt client different gatt_if */
|
||||
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 */
|
||||
uint16_t gatt_if; /*!< Gatt interface id, different application on gatt client different gatt_if */
|
||||
esp_bd_addr_t remote_bda; /*!< Remote bluetooth device address */
|
||||
bool is_connected; /*!< Indicate it is connected or not */
|
||||
} disconnect; /*!< Gatt server callback param of ESP_GATTS_DISCONNECT_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_OPEN_EVT
|
||||
*/
|
||||
/**
|
||||
* @brief ESP_GATTS_CANCEL_OPEN_EVT
|
||||
*/
|
||||
/**
|
||||
* @brief ESP_GATTS_CLOSE_EVT
|
||||
*/
|
||||
/**
|
||||
* @brief ESP_GATTS_LISTEN_EVT
|
||||
*/
|
||||
/**
|
||||
* @brief ESP_GATTS_CONGEST_EVT
|
||||
*/
|
||||
struct gatts_congest_evt_param {
|
||||
uint16_t conn_id; /*!< Connection id */
|
||||
bool congested; /*!< Congested or not */
|
||||
} congest; /*!< Gatt server callback param of ESP_GATTS_CONGEST_EVT */
|
||||
|
||||
/**
|
||||
* @brief ESP_GATTS_RESPONSE_EVT
|
||||
*/
|
||||
struct gatts_rsp_evt_param {
|
||||
esp_gatt_status_t status; /*!< Operation status */
|
||||
uint16_t handle; /*!< Attribute handle which send response */
|
||||
} rsp; /*!< Gatt server callback param of ESP_GATTS_RESPONSE_EVT */
|
||||
} esp_ble_gatts_cb_param_t;
|
||||
|
||||
/**
|
||||
* @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_profile_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] gatt_if: gatt interface id.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_app_unregister(esp_gatt_if_t gatt_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] gatt_if: gatt interface ID
|
||||
* @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 gatt_if,
|
||||
esp_gatt_srvc_id_t *service_id, uint16_t num_handle);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
* @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);
|
||||
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
* @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);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @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 This function is called to read a characteristics descriptor.
|
||||
*
|
||||
* @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 - if this indication expects a confirmation or not.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_send_indicate(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] 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(uint16_t conn_id, uint32_t trans_id,
|
||||
esp_gatt_status_t status, esp_gatt_rsp_t *rsp);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Open a direct open connection or add a background auto connection
|
||||
*
|
||||
* @param[in] gatt_if: application ID.
|
||||
* @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 gatt_if, esp_bd_addr_t remote_bda, bool is_direct);
|
||||
|
||||
/**
|
||||
* @brief Close a connection a remote device.
|
||||
*
|
||||
* @param[in] conn_id: connection ID to be closed.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_gatts_close(uint16_t conn_id);
|
||||
|
||||
|
||||
#endif /* __ESP_GATTS_API_H__ */
|
||||
5533
components/bt/bluedroid/bta/dm/bta_dm_act.c
Normal file
5533
components/bt/bluedroid/bta/dm/bta_dm_act.c
Normal file
File diff suppressed because it is too large
Load Diff
2188
components/bt/bluedroid/bta/dm/bta_dm_api.c
Normal file
2188
components/bt/bluedroid/bta/dm/bta_dm_api.c
Normal file
File diff suppressed because it is too large
Load Diff
580
components/bt/bluedroid/bta/dm/bta_dm_cfg.c
Normal file
580
components/bt/bluedroid/bta/dm/bta_dm_cfg.c
Normal file
@@ -0,0 +1,580 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains compile-time configurable constants for the device
|
||||
* manager.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "bt_target.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_api.h"
|
||||
#include "bta_dm_int.h"
|
||||
// #include "bta_jv_api.h"
|
||||
|
||||
#ifndef BTA_DM_LINK_POLICY_SETTINGS
|
||||
#define BTA_DM_LINK_POLICY_SETTINGS (HCI_ENABLE_MASTER_SLAVE_SWITCH | HCI_ENABLE_HOLD_MODE | HCI_ENABLE_SNIFF_MODE | HCI_ENABLE_PARK_MODE)
|
||||
#endif
|
||||
|
||||
/* page timeout in 625uS */
|
||||
#ifndef BTA_DM_PAGE_TIMEOUT
|
||||
#define BTA_DM_PAGE_TIMEOUT 8192
|
||||
#endif
|
||||
|
||||
/* link supervision timeout in 625uS (5 secs) */
|
||||
#ifndef BTA_DM_LINK_TIMEOUT
|
||||
#define BTA_DM_LINK_TIMEOUT 8000
|
||||
#endif
|
||||
|
||||
/* TRUE to avoid scatternet when av is streaming (be the master) */
|
||||
#ifndef BTA_DM_AVOID_SCATTER_A2DP
|
||||
#define BTA_DM_AVOID_SCATTER_A2DP TRUE
|
||||
#endif
|
||||
|
||||
/* For Insight, PM cfg lookup tables are runtime configurable (to allow tweaking of params for power consumption measurements) */
|
||||
#ifndef BTE_SIM_APP
|
||||
#define tBTA_DM_PM_TYPE_QUALIFIER const
|
||||
#else
|
||||
#define tBTA_DM_PM_TYPE_QUALIFIER
|
||||
#endif
|
||||
|
||||
|
||||
const tBTA_DM_CFG bta_dm_cfg = {
|
||||
/* mobile phone COD */
|
||||
BTA_DM_COD,
|
||||
/* link policy settings */
|
||||
BTA_DM_LINK_POLICY_SETTINGS,
|
||||
/* page timeout in 625uS */
|
||||
BTA_DM_PAGE_TIMEOUT,
|
||||
/* link supervision timeout in 625uS*/
|
||||
BTA_DM_LINK_TIMEOUT,
|
||||
/* TRUE to avoid scatternet when av is streaming (be the master) */
|
||||
BTA_DM_AVOID_SCATTER_A2DP
|
||||
};
|
||||
|
||||
#ifndef BTA_DM_SCATTERNET
|
||||
/* By default, allow partial scatternet */
|
||||
#define BTA_DM_SCATTERNET BTA_DM_PARTIAL_SCATTERNET
|
||||
#endif
|
||||
|
||||
#ifndef BTA_HH_ROLE
|
||||
/* By default, do not specify HH role (backward compatibility) */
|
||||
#define BTA_HH_ROLE BTA_ANY_ROLE
|
||||
#endif
|
||||
|
||||
#ifndef BTA_AV_ROLE
|
||||
/* By default, AV role (backward BTA_MASTER_ROLE_PREF) */
|
||||
#define BTA_AV_ROLE BTA_MASTER_ROLE_PREF
|
||||
#endif
|
||||
|
||||
#ifndef BTA_PANU_ROLE
|
||||
/* By default, AV role (backward BTA_MASTER_ROLE_PREF) */
|
||||
#define BTA_PANU_ROLE BTA_SLAVE_ROLE_ONLY
|
||||
#endif
|
||||
#define BTA_DM_NUM_RM_ENTRY 6
|
||||
|
||||
/* appids for PAN used by insight sample application
|
||||
these have to be same as defined in btui_int.h */
|
||||
#define BTUI_PAN_ID_PANU 0
|
||||
#define BTUI_PAN_ID_NAP 1
|
||||
#define BTUI_PAN_ID_GN 2
|
||||
|
||||
/* First element is always for SYS:
|
||||
app_id = # of entries table, cfg is
|
||||
device scatternet support */
|
||||
const tBTA_DM_RM bta_dm_rm_cfg[] = {
|
||||
{BTA_ID_SYS, BTA_DM_NUM_RM_ENTRY, BTA_DM_SCATTERNET},
|
||||
{BTA_ID_PAN, BTUI_PAN_ID_NAP, BTA_ANY_ROLE},
|
||||
{BTA_ID_PAN, BTUI_PAN_ID_GN, BTA_ANY_ROLE},
|
||||
{BTA_ID_PAN, BTA_APP_ID_PAN_MULTI, BTA_MASTER_ROLE_ONLY},
|
||||
{BTA_ID_PAN, BTUI_PAN_ID_PANU, BTA_PANU_ROLE},
|
||||
{BTA_ID_HH, BTA_ALL_APP_ID, BTA_HH_ROLE},
|
||||
{BTA_ID_AV, BTA_ALL_APP_ID, BTA_AV_ROLE}
|
||||
};
|
||||
|
||||
|
||||
tBTA_DM_CFG *p_bta_dm_cfg = (tBTA_DM_CFG *) &bta_dm_cfg;
|
||||
|
||||
tBTA_DM_RM *p_bta_dm_rm_cfg = (tBTA_DM_RM *) &bta_dm_rm_cfg;
|
||||
|
||||
#if BLE_INCLUDED == TRUE
|
||||
# define BTA_DM_NUM_PM_ENTRY 21 /* number of entries in bta_dm_pm_cfg except the first */
|
||||
# define BTA_DM_NUM_PM_SPEC 15 /* number of entries in bta_dm_pm_spec */
|
||||
#else
|
||||
# define BTA_DM_NUM_PM_ENTRY 19 /* number of entries in bta_dm_pm_cfg except the first */
|
||||
# define BTA_DM_NUM_PM_SPEC 13 /* number of entries in bta_dm_pm_spec */
|
||||
#endif
|
||||
|
||||
tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_CFG bta_dm_pm_cfg[BTA_DM_NUM_PM_ENTRY + 1] = {
|
||||
{BTA_ID_SYS, BTA_DM_NUM_PM_ENTRY, 0}, /* reserved: specifies length of this table. */
|
||||
{BTA_ID_AG, BTA_ALL_APP_ID, 0}, /* ag uses first spec table for app id 0 */
|
||||
{BTA_ID_CT, 1, 1}, /* ct (BTA_ID_CT,APP ID=1) spec table */
|
||||
{BTA_ID_CG, BTA_ALL_APP_ID, 1}, /* cg resue ct spec table */
|
||||
{BTA_ID_DG, BTA_ALL_APP_ID, 2}, /* dg spec table */
|
||||
{BTA_ID_AV, BTA_ALL_APP_ID, 4}, /* av spec table */
|
||||
{BTA_ID_AVK, BTA_ALL_APP_ID, 12}, /* avk spec table */
|
||||
{BTA_ID_FTC, BTA_ALL_APP_ID, 6}, /* ftc spec table */
|
||||
{BTA_ID_FTS, BTA_ALL_APP_ID, 7}, /* fts spec table */
|
||||
{BTA_ID_HD, BTA_ALL_APP_ID, 3}, /* hd spec table */
|
||||
{BTA_ID_HH, BTA_ALL_APP_ID, 5}, /* hh spec table */
|
||||
{BTA_ID_PBC, BTA_ALL_APP_ID, 2}, /* reuse dg spec table */
|
||||
{BTA_ID_PBS, BTA_ALL_APP_ID, 7}, /* reuse fts spec table */
|
||||
{BTA_ID_OPC, BTA_ALL_APP_ID, 6}, /* reuse ftc spec table */
|
||||
{BTA_ID_OPS, BTA_ALL_APP_ID, 7}, /* reuse fts spec table */
|
||||
{BTA_ID_MSE, BTA_ALL_APP_ID, 7}, /* reuse fts spec table */
|
||||
// {BTA_ID_JV, BTA_JV_PM_ID_1, 6}, /* app BTA_JV_PM_ID_1, reuse ftc spec table */
|
||||
// {BTA_ID_JV, BTA_ALL_APP_ID, 7}, /* reuse fts spec table */
|
||||
{BTA_ID_HL, BTA_ALL_APP_ID, 8}, /* reuse fts spec table */
|
||||
{BTA_ID_PAN, BTUI_PAN_ID_PANU, 9}, /* PANU spec table */
|
||||
{BTA_ID_PAN, BTUI_PAN_ID_NAP, 10}, /* NAP spec table */
|
||||
{BTA_ID_HS, BTA_ALL_APP_ID, 11} /* HS spec table */
|
||||
#if BLE_INCLUDED == TRUE
|
||||
, {BTA_ID_GATTC, BTA_ALL_APP_ID, 13} /* gattc spec table */
|
||||
, {BTA_ID_GATTS, BTA_ALL_APP_ID, 14} /* gatts spec table */
|
||||
#endif
|
||||
};
|
||||
|
||||
tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
|
||||
/* AG : 0 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_SNIFF_SCO_OPEN_IDX, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_RETRY, 7000}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* CT, CG : 1 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_PARK, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open park */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open sniff */
|
||||
{{BTA_DM_PM_PARK, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close park */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_RETRY, 5000}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* DG, PBC : 2 */
|
||||
{
|
||||
(BTA_DM_PM_ACTIVE), /* no power saving mode allowed */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open active */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF, 1000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* HD : 3 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR3), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF_HD_ACTIVE_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF_HD_IDLE_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_SNIFF_HD_ACTIVE_IDX, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* AV : 4 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF), /* allow sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* HH : 5 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR1), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF_HH_OPEN_IDX, BTA_DM_PM_HH_OPEN_DELAY}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close, used for HH suspend */
|
||||
{{BTA_DM_PM_SNIFF_HH_IDLE_IDX, BTA_DM_PM_HH_IDLE_DELAY}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_SNIFF_HH_ACTIVE_IDX, BTA_DM_PM_HH_ACTIVE_DELAY}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* FTC, OPC, JV : 6 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF), /* allow sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open active */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* FTS, PBS, OPS, MSE, BTA_JV_PM_ID_1 : 7 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF), /* allow sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open active */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, BTA_FTS_OPS_IDLE_TO_SNIFF_DELAY_MS}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* HL : 8 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF), /* allow sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* PANU : 9 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF), /* allow sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open active */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* NAP : 10 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF), /* allow sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open active */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 5000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* HS : 11 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_SNIFF3, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
|
||||
{{BTA_DM_PM_SNIFF, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff */
|
||||
{{BTA_DM_PM_SNIFF, 7000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_RETRY, 7000}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
},
|
||||
|
||||
/* AVK : 12 */
|
||||
{
|
||||
(BTA_DM_PM_SNIFF), /* allow sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF, 3000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open sniff */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF4, 3000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
}
|
||||
|
||||
#if BLE_INCLUDED == TRUE
|
||||
/* GATTC : 13 */
|
||||
, {
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 10000}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open active */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_SNIFF_A2DP_IDX, 10000}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
#if defined(AMP_INCLUDED) && (AMP_INCLUDED == TRUE)
|
||||
{{BTA_DM_PM_NO_ACTION, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* amp */
|
||||
#endif
|
||||
{{BTA_DM_PM_RETRY, 5000}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
}
|
||||
/* GATTS : 14 */
|
||||
, {
|
||||
(BTA_DM_PM_SNIFF | BTA_DM_PM_PARK), /* allow park & sniff */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
(BTA_DM_PM_SSR2), /* the SSR entry */
|
||||
#endif
|
||||
{
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn open active */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* conn close */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app open */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* app close */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
#if defined(AMP_INCLUDED) && (AMP_INCLUDED == TRUE)
|
||||
{{BTA_DM_PM_NO_PREF, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* amp */
|
||||
#endif
|
||||
{{BTA_DM_PM_RETRY, 5000}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BTE_SIM_APP /* For Insight builds only */
|
||||
/* Entries at the end of the pm_spec table are user-defined (runtime configurable),
|
||||
for power consumption experiments.
|
||||
Insight finds the first user-defined entry by looking for the first BTA_DM_PM_NO_PREF.
|
||||
The number of user_defined specs is defined by BTA_SWRAP_UD_PM_SPEC_COUNT */
|
||||
,
|
||||
{BTA_DM_PM_NO_PREF}, /* pm_spec USER_DEFINED_0 */
|
||||
{BTA_DM_PM_NO_PREF} /* pm_spec USER_DEFINED_1 */
|
||||
#endif /* BTE_SIM_APP */
|
||||
};
|
||||
|
||||
/* Please refer to the SNIFF table definitions in bta_api.h.
|
||||
*
|
||||
* Adding to or Modifying the Table
|
||||
* Additional sniff parameter entries can be added for BTA_DM_PM_SNIFF5 - BTA_DM_PM_SNIFF7.
|
||||
* Overrides of additional table entries can be specified in bdroid_buildcfg.h. If additional
|
||||
* sniff parameter entries are added or an override of an existing entry is specified in
|
||||
* bdroid_buildcfg.h then the BTA_DM_PM_*_IDX defines in bta_api.h will need to be match the new
|
||||
* ordering.
|
||||
*
|
||||
* Table Ordering
|
||||
* Sniff Table entries must be ordered from highest latency (biggest interval) to lowest latency.
|
||||
* If there is a conflict among the connected services the setting with the lowest latency will
|
||||
* be selected.
|
||||
*/
|
||||
tBTA_DM_PM_TYPE_QUALIFIER tBTM_PM_PWR_MD bta_dm_pm_md[] = {
|
||||
/*
|
||||
* More sniff parameter entries can be added for
|
||||
* BTA_DM_PM_SNIFF3 - BTA_DM_PM_SNIFF7, if needed. When entries are added or
|
||||
* removed, BTA_DM_PM_PARK_IDX needs to be updated to reflect the actual index
|
||||
* BTA_DM_PM_PARK_IDX is defined in bta_api.h and can be override by the
|
||||
* bdroid_buildcfg.h settings.
|
||||
* The SNIFF table entries must be in the order from highest latency (biggest
|
||||
* interval) to lowest latency. If there's a conflict among the connected
|
||||
* services, the setting with lowest latency wins.
|
||||
*/
|
||||
/* sniff modes: max interval, min interval, attempt, timeout */
|
||||
{BTA_DM_PM_SNIFF_MAX, BTA_DM_PM_SNIFF_MIN, BTA_DM_PM_SNIFF_ATTEMPT, BTA_DM_PM_SNIFF_TIMEOUT, BTM_PM_MD_SNIFF}, /* for BTA_DM_PM_SNIFF - A2DP */
|
||||
{BTA_DM_PM_SNIFF1_MAX, BTA_DM_PM_SNIFF1_MIN, BTA_DM_PM_SNIFF1_ATTEMPT, BTA_DM_PM_SNIFF1_TIMEOUT, BTM_PM_MD_SNIFF}, /* for BTA_DM_PM_SNIFF1 */
|
||||
{BTA_DM_PM_SNIFF2_MAX, BTA_DM_PM_SNIFF2_MIN, BTA_DM_PM_SNIFF2_ATTEMPT, BTA_DM_PM_SNIFF2_TIMEOUT, BTM_PM_MD_SNIFF}, /* for BTA_DM_PM_SNIFF2- HD idle */
|
||||
{BTA_DM_PM_SNIFF3_MAX, BTA_DM_PM_SNIFF3_MIN, BTA_DM_PM_SNIFF3_ATTEMPT, BTA_DM_PM_SNIFF3_TIMEOUT, BTM_PM_MD_SNIFF}, /* for BTA_DM_PM_SNIFF3- SCO open */
|
||||
{BTA_DM_PM_SNIFF4_MAX, BTA_DM_PM_SNIFF4_MIN, BTA_DM_PM_SNIFF4_ATTEMPT, BTA_DM_PM_SNIFF4_TIMEOUT, BTM_PM_MD_SNIFF}, /* for BTA_DM_PM_SNIFF4- HD active */
|
||||
{BTA_DM_PM_SNIFF5_MAX, BTA_DM_PM_SNIFF5_MIN, BTA_DM_PM_SNIFF5_ATTEMPT, BTA_DM_PM_SNIFF5_TIMEOUT, BTM_PM_MD_SNIFF}, /* for BTA_DM_PM_SNIFF5- HD active */
|
||||
{BTA_DM_PM_PARK_MAX, BTA_DM_PM_PARK_MIN, BTA_DM_PM_PARK_ATTEMPT, BTA_DM_PM_PARK_TIMEOUT, BTM_PM_MD_PARK}
|
||||
|
||||
#ifdef BTE_SIM_APP /* For Insight builds only */
|
||||
/* Entries at the end of the bta_dm_pm_md table are user-defined (runtime configurable),
|
||||
for power consumption experiments.
|
||||
Insight finds the first user-defined entry by looking for the first 'max=0'.
|
||||
The number of user_defined specs is defined by BTA_SWRAP_UD_PM_DM_COUNT */
|
||||
,
|
||||
{0}, /* CONN_OPEN/SCO_CLOSE power mode settings for pm_spec USER_DEFINED_0 */
|
||||
{0}, /* SCO_OPEN power mode settings for pm_spec USER_DEFINED_0 */
|
||||
|
||||
{0}, /* CONN_OPEN/SCO_CLOSE power mode settings for pm_spec USER_DEFINED_1 */
|
||||
{0} /* SCO_OPEN power mode settings for pm_spec USER_DEFINED_1 */
|
||||
#endif /* BTE_SIM_APP */
|
||||
};
|
||||
|
||||
/* 0=max_lat -> no SSR */
|
||||
/* the smaller of the SSR max latency wins.
|
||||
* the entries in this table must be from highest latency (biggest interval) to lowest latency */
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
tBTA_DM_SSR_SPEC bta_dm_ssr_spec[] = {
|
||||
/*max_lat, min_rmt_to, min_loc_to*/
|
||||
{0, 0, 0}, /* BTA_DM_PM_SSR0 - do not use SSR */
|
||||
{0, 0, 2}, /* BTA_DM_PM_SSR1 - HH, can NOT share entry with any other profile,
|
||||
seting default max latency and min remote timeout as 0,
|
||||
and always read individual device preference from HH module */
|
||||
{1200, 2, 2}, /* BTA_DM_PM_SSR2 - others (as long as sniff is allowed)*/
|
||||
{360, 160, 2} /* BTA_DM_PM_SSR3 - HD */
|
||||
};
|
||||
|
||||
tBTA_DM_SSR_SPEC *p_bta_dm_ssr_spec = (tBTA_DM_SSR_SPEC *) &bta_dm_ssr_spec;
|
||||
#endif
|
||||
|
||||
tBTA_DM_PM_CFG *p_bta_dm_pm_cfg = (tBTA_DM_PM_CFG *) &bta_dm_pm_cfg;
|
||||
tBTA_DM_PM_SPEC *p_bta_dm_pm_spec = (tBTA_DM_PM_SPEC *) &bta_dm_pm_spec;
|
||||
tBTM_PM_PWR_MD *p_bta_dm_pm_md = (tBTM_PM_PWR_MD *) &bta_dm_pm_md;
|
||||
|
||||
/* The performance impact of EIR packet size
|
||||
**
|
||||
** When BTM_EIR_DEFAULT_FEC_REQUIRED is TRUE,
|
||||
** 1 to 17 bytes, DM1 is used and most robust.
|
||||
** 18 to 121 bytes, DM3 is used but impacts inquiry scan time with large number
|
||||
** of devices.(almost double with 150 users)
|
||||
** 122 to 224 bytes, DM5 is used but cause quite big performance loss even with
|
||||
** small number of users. so it is not recommended.
|
||||
** 225 to 240 bytes, DH5 is used without FEC but it not recommended.
|
||||
** (same reason of DM5)
|
||||
**
|
||||
** When BTM_EIR_DEFAULT_FEC_REQUIRED is FALSE,
|
||||
** 1 to 27 bytes, DH1 is used but only robust at short range.
|
||||
** 28 to 183 bytes, DH3 is used but only robust at short range and impacts inquiry
|
||||
** scan time with large number of devices.
|
||||
** 184 to 240 bytes, DH5 is used but it not recommended.
|
||||
*/
|
||||
|
||||
#if (BTA_EIR_CANNED_UUID_LIST == TRUE)
|
||||
/* for example */
|
||||
const UINT8 bta_dm_eir_uuid16_list[] = { 0x08, 0x11, /* Headset */
|
||||
0x1E, 0x11, /* Handsfree */
|
||||
0x0E, 0x11, /* AV Remote Control */
|
||||
0x0B, 0x11, /* Audio Sink */
|
||||
};
|
||||
#endif // BTA_EIR_CANNED_UUID_LIST
|
||||
|
||||
/* Extended Inquiry Response */
|
||||
const tBTA_DM_EIR_CONF bta_dm_eir_cfg = {
|
||||
50, /* minimum length of local name when it is shortened */
|
||||
/* if length of local name is longer than this and EIR has not enough */
|
||||
/* room for all UUID list then local name is shortened to this length */
|
||||
#if (BTA_EIR_CANNED_UUID_LIST == TRUE)
|
||||
8,
|
||||
(UINT8 *)bta_dm_eir_uuid16_list,
|
||||
#else // BTA_EIR_CANNED_UUID_LIST
|
||||
{ /* mask of UUID list in EIR */
|
||||
0xFFFFFFFF, /* LSB is the first UUID of the first 32 UUIDs in BTM_EIR_UUID_LKUP_TBL */
|
||||
0xFFFFFFFF /* LSB is the first UUID of the next 32 UUIDs in BTM_EIR_UUID_LKUP_TBL */
|
||||
/* BTM_EIR_UUID_LKUP_TBL can be overrided */
|
||||
},
|
||||
#endif // BTA_EIR_CANNED_UUID_LIST
|
||||
NULL, /* Inquiry TX power */
|
||||
0, /* length of flags in bytes */
|
||||
NULL, /* flags for EIR */
|
||||
0, /* length of manufacturer specific in bytes */
|
||||
NULL, /* manufacturer specific */
|
||||
0, /* length of additional data in bytes */
|
||||
NULL /* additional data */
|
||||
};
|
||||
tBTA_DM_EIR_CONF *p_bta_dm_eir_cfg = (tBTA_DM_EIR_CONF *) &bta_dm_eir_cfg;
|
||||
114
components/bt/bluedroid/bta/dm/bta_dm_ci.c
Normal file
114
components/bt/bluedroid/bta/dm/bta_dm_ci.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the API implementation file for the BTA device manager.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "gki.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_api.h"
|
||||
#include "bta_dm_int.h"
|
||||
#include <string.h>
|
||||
#include "bta_dm_ci.h"
|
||||
|
||||
|
||||
#if (BTM_OOB_INCLUDED == TRUE)
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_ci_io_req
|
||||
**
|
||||
** Description This function must be called in response to function
|
||||
** bta_dm_co_io_req(), if *p_oob_data to BTA_OOB_UNKNOWN
|
||||
** by bta_dm_co_io_req().
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_dm_ci_io_req(BD_ADDR bd_addr, tBTA_IO_CAP io_cap, tBTA_OOB_DATA oob_data,
|
||||
tBTA_AUTH_REQ auth_req)
|
||||
|
||||
{
|
||||
tBTA_DM_CI_IO_REQ *p_msg;
|
||||
|
||||
if ((p_msg = (tBTA_DM_CI_IO_REQ *) GKI_getbuf(sizeof(tBTA_DM_CI_IO_REQ))) != NULL) {
|
||||
p_msg->hdr.event = BTA_DM_CI_IO_REQ_EVT;
|
||||
bdcpy(p_msg->bd_addr, bd_addr);
|
||||
p_msg->io_cap = io_cap;
|
||||
p_msg->oob_data = oob_data;
|
||||
p_msg->auth_req = auth_req;
|
||||
bta_sys_sendmsg(p_msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_ci_rmt_oob
|
||||
**
|
||||
** Description This function must be called in response to function
|
||||
** bta_dm_co_rmt_oob() to provide the OOB data associated
|
||||
** with the remote device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_dm_ci_rmt_oob(BOOLEAN accept, BD_ADDR bd_addr, BT_OCTET16 c, BT_OCTET16 r)
|
||||
{
|
||||
tBTA_DM_CI_RMT_OOB *p_msg;
|
||||
|
||||
if ((p_msg = (tBTA_DM_CI_RMT_OOB *) GKI_getbuf(sizeof(tBTA_DM_CI_RMT_OOB))) != NULL) {
|
||||
p_msg->hdr.event = BTA_DM_CI_RMT_OOB_EVT;
|
||||
bdcpy(p_msg->bd_addr, bd_addr);
|
||||
p_msg->accept = accept;
|
||||
memcpy(p_msg->c, c, BT_OCTET16_LEN);
|
||||
memcpy(p_msg->r, r, BT_OCTET16_LEN);
|
||||
bta_sys_sendmsg(p_msg);
|
||||
}
|
||||
}
|
||||
#endif /* BTM_OOB_INCLUDED */
|
||||
|
||||
#if (BTM_SCO_HCI_INCLUDED == TRUE)
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sco_ci_data_ready
|
||||
**
|
||||
** Description This function sends an event to indicating that the phone
|
||||
** has SCO data ready.
|
||||
**
|
||||
** Parameters event: is obtained from bta_dm_sco_co_open() function, which
|
||||
** is the BTA event we want to send back to BTA module
|
||||
** when there is encoded data ready.
|
||||
** sco_handle: is the BTA sco handle which indicate a specific
|
||||
** SCO connection.
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_dm_sco_ci_data_ready(UINT16 event, UINT16 sco_handle)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = event;
|
||||
p_buf->layer_specific = sco_handle;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
1163
components/bt/bluedroid/bta/dm/bta_dm_int.h
Normal file
1163
components/bt/bluedroid/bta/dm/bta_dm_int.h
Normal file
File diff suppressed because it is too large
Load Diff
369
components/bt/bluedroid/bta/dm/bta_dm_main.c
Normal file
369
components/bt/bluedroid/bta/dm/bta_dm_main.c
Normal file
@@ -0,0 +1,369 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the main implementation file for the BTA device manager.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bta_api.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_dm_int.h"
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and types
|
||||
*****************************************************************************/
|
||||
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
tBTA_DM_CB bta_dm_cb;
|
||||
tBTA_DM_SEARCH_CB bta_dm_search_cb;
|
||||
tBTA_DM_DI_CB bta_dm_di_cb;
|
||||
#endif
|
||||
|
||||
|
||||
#define BTA_DM_NUM_ACTIONS (BTA_DM_MAX_EVT & 0x00ff)
|
||||
|
||||
/* type for action functions */
|
||||
typedef void (*tBTA_DM_ACTION)(tBTA_DM_MSG *p_data);
|
||||
|
||||
/* action function list */
|
||||
const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
|
||||
|
||||
/* device manager local device API events */
|
||||
bta_dm_enable, /* 0 BTA_DM_API_ENABLE_EVT */
|
||||
bta_dm_disable, /* 1 BTA_DM_API_DISABLE_EVT */
|
||||
bta_dm_set_dev_name, /* 2 BTA_DM_API_SET_NAME_EVT */
|
||||
bta_dm_set_visibility, /* 3 BTA_DM_API_SET_VISIBILITY_EVT */
|
||||
bta_dm_acl_change, /* 8 BTA_DM_ACL_CHANGE_EVT */
|
||||
bta_dm_add_device, /* 9 BTA_DM_API_ADD_DEVICE_EVT */
|
||||
bta_dm_close_acl, /* 10 BTA_DM_API_ADD_DEVICE_EVT */
|
||||
|
||||
/* security API events */
|
||||
bta_dm_bond, /* 11 BTA_DM_API_BOND_EVT */
|
||||
bta_dm_bond_cancel, /* 12 BTA_DM_API_BOND_CANCEL_EVT */
|
||||
bta_dm_pin_reply, /* 13 BTA_DM_API_PIN_REPLY_EVT */
|
||||
|
||||
/* power manger events */
|
||||
bta_dm_pm_btm_status, /* 16 BTA_DM_PM_BTM_STATUS_EVT */
|
||||
bta_dm_pm_timer, /* 17 BTA_DM_PM_TIMER_EVT*/
|
||||
|
||||
/* simple pairing events */
|
||||
bta_dm_confirm, /* 18 BTA_DM_API_CONFIRM_EVT */
|
||||
|
||||
bta_dm_set_encryption, /* BTA_DM_API_SET_ENCRYPTION_EVT */
|
||||
|
||||
#if (BTM_OOB_INCLUDED == TRUE)
|
||||
bta_dm_loc_oob, /* 20 BTA_DM_API_LOC_OOB_EVT */
|
||||
bta_dm_ci_io_req_act, /* 21 BTA_DM_CI_IO_REQ_EVT */
|
||||
bta_dm_ci_rmt_oob_act, /* 22 BTA_DM_CI_RMT_OOB_EVT */
|
||||
#endif /* BTM_OOB_INCLUDED */
|
||||
|
||||
|
||||
#if BLE_INCLUDED == TRUE
|
||||
bta_dm_add_blekey, /* BTA_DM_API_ADD_BLEKEY_EVT */
|
||||
bta_dm_add_ble_device, /* BTA_DM_API_ADD_BLEDEVICE_EVT */
|
||||
bta_dm_ble_passkey_reply, /* BTA_DM_API_BLE_PASSKEY_REPLY_EVT */
|
||||
bta_dm_ble_confirm_reply, /* BTA_DM_API_BLE_CONFIRM_REPLY_EVT */
|
||||
bta_dm_security_grant,
|
||||
bta_dm_ble_set_bg_conn_type,
|
||||
bta_dm_ble_set_conn_params, /* BTA_DM_API_BLE_CONN_PARAM_EVT */
|
||||
bta_dm_ble_set_conn_scan_params, /* BTA_DM_API_BLE_CONN_SCAN_PARAM_EVT */
|
||||
bta_dm_ble_set_scan_params, /* BTA_DM_API_BLE_SCAN_PARAM_EVT */
|
||||
bta_dm_ble_set_scan_fil_params, /* BTA_DM_API_BLE_SCAN_FIL_PARAM_EVT */
|
||||
bta_dm_ble_observe, /* BTA_DM_API_BLE_OBSERVE_EVT*/
|
||||
bta_dm_ble_update_conn_params, /* BTA_DM_API_UPDATE_CONN_PARAM_EVT */
|
||||
/*******This handler function added by Yulong at 2016/9/9 to
|
||||
support the random address setting for the APP******/
|
||||
bta_dm_ble_set_rand_address, /*BTA_DM_API_SET_RAND_ADDR_EVT*/
|
||||
/*******This handler function added by Yulong at 2016/10/19 to
|
||||
support stop the ble advertising setting by the APP******/
|
||||
bta_dm_ble_stop_advertising, /*BTA_DM_API_BLE_STOP_ADV_EVT*/
|
||||
#if BLE_PRIVACY_SPT == TRUE
|
||||
bta_dm_ble_config_local_privacy, /* BTA_DM_API_LOCAL_PRIVACY_EVT */
|
||||
#endif
|
||||
bta_dm_ble_set_adv_params, /* BTA_DM_API_BLE_ADV_PARAM_EVT */
|
||||
bta_dm_ble_set_adv_params_all, /* BTA_DM_API_BLE_ADV_PARAM_All_EVT */
|
||||
bta_dm_ble_set_adv_config, /* BTA_DM_API_BLE_SET_ADV_CONFIG_EVT */
|
||||
bta_dm_ble_set_scan_rsp, /* BTA_DM_API_BLE_SET_SCAN_RSPT */
|
||||
bta_dm_ble_broadcast, /* BTA_DM_API_BLE_BROADCAST_EVT */
|
||||
bta_dm_ble_set_data_length, /* BTA_DM_API_SET_DATA_LENGTH_EVT */
|
||||
#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
|
||||
bta_dm_cfg_filter_cond, /* BTA_DM_API_CFG_FILTER_COND_EVT */
|
||||
bta_dm_scan_filter_param_setup, /* BTA_DM_API_SCAN_FILTER_SETUP_EVT */
|
||||
bta_dm_enable_scan_filter, /* BTA_DM_API_SCAN_FILTER_ENABLE_EVT */
|
||||
#endif
|
||||
bta_dm_ble_multi_adv_enb, /* BTA_DM_API_BLE_MULTI_ADV_ENB_EVT*/
|
||||
bta_dm_ble_multi_adv_upd_param, /* BTA_DM_API_BLE_MULTI_ADV_PARAM_UPD_EVT */
|
||||
bta_dm_ble_multi_adv_data, /* BTA_DM_API_BLE_MULTI_ADV_DATA_EVT */
|
||||
btm_dm_ble_multi_adv_disable, /* BTA_DM_API_BLE_MULTI_ADV_DISABLE_EVT */
|
||||
bta_dm_ble_setup_storage, /* BTA_DM_API_BLE_SETUP_STORAGE_EVT */
|
||||
bta_dm_ble_enable_batch_scan, /* BTA_DM_API_BLE_ENABLE_BATCH_SCAN_EVT */
|
||||
bta_dm_ble_disable_batch_scan, /* BTA_DM_API_BLE_DISABLE_BATCH_SCAN_EVT */
|
||||
bta_dm_ble_read_scan_reports, /* BTA_DM_API_BLE_READ_SCAN_REPORTS_EVT */
|
||||
bta_dm_ble_track_advertiser, /* BTA_DM_API_BLE_TRACK_ADVERTISER_EVT */
|
||||
bta_dm_ble_get_energy_info, /* BTA_DM_API_BLE_ENERGY_INFO_EVT */
|
||||
#endif
|
||||
|
||||
bta_dm_enable_test_mode, /* BTA_DM_API_ENABLE_TEST_MODE_EVT */
|
||||
bta_dm_disable_test_mode, /* BTA_DM_API_DISABLE_TEST_MODE_EVT */
|
||||
bta_dm_execute_callback, /* BTA_DM_API_EXECUTE_CBACK_EVT */
|
||||
|
||||
bta_dm_remove_all_acl, /* BTA_DM_API_REMOVE_ALL_ACL_EVT */
|
||||
bta_dm_remove_device, /* BTA_DM_API_REMOVE_DEVICE_EVT */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* state machine action enumeration list */
|
||||
enum {
|
||||
BTA_DM_API_SEARCH, /* 0 bta_dm_search_start */
|
||||
BTA_DM_API_SEARCH_CANCEL, /* 1 bta_dm_search_cancel */
|
||||
BTA_DM_API_DISCOVER, /* 2 bta_dm_discover */
|
||||
BTA_DM_INQUIRY_CMPL, /* 3 bta_dm_inq_cmpl */
|
||||
BTA_DM_REMT_NAME, /* 4 bta_dm_rmt_name */
|
||||
BTA_DM_SDP_RESULT, /* 5 bta_dm_sdp_result */
|
||||
BTA_DM_SEARCH_CMPL, /* 6 bta_dm_search_cmpl*/
|
||||
BTA_DM_FREE_SDP_DB, /* 7 bta_dm_free_sdp_db */
|
||||
BTA_DM_DISC_RESULT, /* 8 bta_dm_disc_result */
|
||||
BTA_DM_SEARCH_RESULT, /* 9 bta_dm_search_result */
|
||||
BTA_DM_QUEUE_SEARCH, /* 10 bta_dm_queue_search */
|
||||
BTA_DM_QUEUE_DISC, /* 11 bta_dm_queue_disc */
|
||||
BTA_DM_SEARCH_CLEAR_QUEUE, /* 12 bta_dm_search_clear_queue */
|
||||
BTA_DM_SEARCH_CANCEL_CMPL, /* 13 bta_dm_search_cancel_cmpl */
|
||||
BTA_DM_SEARCH_CANCEL_NOTIFY, /* 14 bta_dm_search_cancel_notify */
|
||||
BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL, /* 15 bta_dm_search_cancel_transac_cmpl */
|
||||
BTA_DM_DISC_RMT_NAME, /* 16 bta_dm_disc_rmt_name */
|
||||
BTA_DM_API_DI_DISCOVER, /* 17 bta_dm_di_disc */
|
||||
#if BLE_INCLUDED == TRUE
|
||||
BTA_DM_CLOSE_GATT_CONN, /* 18 bta_dm_close_gatt_conn */
|
||||
#endif
|
||||
BTA_DM_SEARCH_NUM_ACTIONS /* 19 */
|
||||
};
|
||||
|
||||
|
||||
/* action function list */
|
||||
const tBTA_DM_ACTION bta_dm_search_action[] = {
|
||||
|
||||
bta_dm_search_start, /* 0 BTA_DM_API_SEARCH */
|
||||
bta_dm_search_cancel, /* 1 BTA_DM_API_SEARCH_CANCEL */
|
||||
bta_dm_discover, /* 2 BTA_DM_API_DISCOVER */
|
||||
bta_dm_inq_cmpl, /* 3 BTA_DM_INQUIRY_CMPL */
|
||||
bta_dm_rmt_name, /* 4 BTA_DM_REMT_NAME */
|
||||
bta_dm_sdp_result, /* 5 BTA_DM_SDP_RESULT */
|
||||
bta_dm_search_cmpl, /* 6 BTA_DM_SEARCH_CMPL */
|
||||
bta_dm_free_sdp_db, /* 7 BTA_DM_FREE_SDP_DB */
|
||||
bta_dm_disc_result, /* 8 BTA_DM_DISC_RESULT */
|
||||
bta_dm_search_result, /* 9 BTA_DM_SEARCH_RESULT */
|
||||
bta_dm_queue_search, /* 10 BTA_DM_QUEUE_SEARCH */
|
||||
bta_dm_queue_disc, /* 11 BTA_DM_QUEUE_DISC */
|
||||
bta_dm_search_clear_queue, /* 12 BTA_DM_SEARCH_CLEAR_QUEUE */
|
||||
bta_dm_search_cancel_cmpl, /* 13 BTA_DM_SEARCH_CANCEL_CMPL */
|
||||
bta_dm_search_cancel_notify, /* 14 BTA_DM_SEARCH_CANCEL_NOTIFY */
|
||||
bta_dm_search_cancel_transac_cmpl, /* 15 BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL */
|
||||
bta_dm_disc_rmt_name, /* 16 BTA_DM_DISC_RMT_NAME */
|
||||
bta_dm_di_disc /* 17 BTA_DM_API_DI_DISCOVER */
|
||||
#if BLE_INCLUDED == TRUE
|
||||
, bta_dm_close_gatt_conn
|
||||
#endif
|
||||
};
|
||||
|
||||
#define BTA_DM_SEARCH_IGNORE BTA_DM_SEARCH_NUM_ACTIONS
|
||||
/* state table information */
|
||||
#define BTA_DM_SEARCH_ACTIONS 2 /* number of actions */
|
||||
#define BTA_DM_SEARCH_NEXT_STATE 2 /* position of next state */
|
||||
#define BTA_DM_SEARCH_NUM_COLS 3 /* number of columns in state tables */
|
||||
|
||||
|
||||
|
||||
/* state table for listen state */
|
||||
const UINT8 bta_dm_search_idle_st_table[][BTA_DM_SEARCH_NUM_COLS] = {
|
||||
|
||||
/* Event Action 1 Action 2 Next State */
|
||||
/* API_SEARCH */ {BTA_DM_API_SEARCH, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE},
|
||||
/* API_SEARCH_CANCEL */ {BTA_DM_SEARCH_CANCEL_NOTIFY, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
/* API_SEARCH_DISC */ {BTA_DM_API_DISCOVER, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE},
|
||||
/* INQUIRY_CMPL */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
/* REMT_NAME_EVT */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
/* SDP_RESULT_EVT */ {BTA_DM_FREE_SDP_DB, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
/* SEARCH_CMPL_EVT */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
/* DISCV_RES_EVT */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
/* API_DI_DISCOVER_EVT */ {BTA_DM_API_DI_DISCOVER, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE}
|
||||
#if BLE_INCLUDED == TRUE
|
||||
/* DISC_CLOSE_TOUT_EVT */ , {BTA_DM_CLOSE_GATT_CONN, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE}
|
||||
#endif
|
||||
};
|
||||
const UINT8 bta_dm_search_search_active_st_table[][BTA_DM_SEARCH_NUM_COLS] = {
|
||||
|
||||
/* Event Action 1 Action 2 Next State */
|
||||
/* API_SEARCH */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE},
|
||||
/* API_SEARCH_CANCEL */ {BTA_DM_API_SEARCH_CANCEL, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_CANCELLING},
|
||||
/* API_SEARCH_DISC */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE},
|
||||
/* INQUIRY_CMPL */ {BTA_DM_INQUIRY_CMPL, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE},
|
||||
/* REMT_NAME_EVT */ {BTA_DM_REMT_NAME, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE},
|
||||
/* SDP_RESULT_EVT */ {BTA_DM_SDP_RESULT, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE},
|
||||
/* SEARCH_CMPL_EVT */ {BTA_DM_SEARCH_CMPL, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
/* DISCV_RES_EVT */ {BTA_DM_SEARCH_RESULT, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE},
|
||||
/* API_DI_DISCOVER_EVT */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE}
|
||||
#if BLE_INCLUDED == TRUE
|
||||
/* DISC_CLOSE_TOUT_EVT */ , {BTA_DM_CLOSE_GATT_CONN, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_ACTIVE}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
const UINT8 bta_dm_search_search_cancelling_st_table[][BTA_DM_SEARCH_NUM_COLS] = {
|
||||
|
||||
/* Event Action 1 Action 2 Next State */
|
||||
/* API_SEARCH */ {BTA_DM_QUEUE_SEARCH, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_CANCELLING},
|
||||
/* API_SEARCH_CANCEL */ {BTA_DM_SEARCH_CLEAR_QUEUE, BTA_DM_SEARCH_CANCEL_NOTIFY, BTA_DM_SEARCH_CANCELLING},
|
||||
/* API_SEARCH_DISC */ {BTA_DM_QUEUE_DISC, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_CANCELLING},
|
||||
/* INQUIRY_CMPL */ {BTA_DM_SEARCH_CANCEL_CMPL, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
/* REMT_NAME_EVT */ {BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL, BTA_DM_SEARCH_CANCEL_CMPL, BTA_DM_SEARCH_IDLE},
|
||||
/* SDP_RESULT_EVT */ {BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL, BTA_DM_SEARCH_CANCEL_CMPL, BTA_DM_SEARCH_IDLE},
|
||||
/* SEARCH_CMPL_EVT */ {BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL, BTA_DM_SEARCH_CANCEL_CMPL, BTA_DM_SEARCH_IDLE},
|
||||
/* DISCV_RES_EVT */ {BTA_DM_SEARCH_CANCEL_TRANSAC_CMPL, BTA_DM_SEARCH_CANCEL_CMPL, BTA_DM_SEARCH_IDLE},
|
||||
/* API_DI_DISCOVER_EVT */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_CANCELLING}
|
||||
#if BLE_INCLUDED == TRUE
|
||||
/* DISC_CLOSE_TOUT_EVT */ , {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_CANCELLING}
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
const UINT8 bta_dm_search_disc_active_st_table[][BTA_DM_SEARCH_NUM_COLS] = {
|
||||
|
||||
/* Event Action 1 Action 2 Next State */
|
||||
/* API_SEARCH */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE},
|
||||
/* API_SEARCH_CANCEL */ {BTA_DM_SEARCH_CANCEL_NOTIFY, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_CANCELLING},
|
||||
/* API_SEARCH_DISC */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE},
|
||||
/* INQUIRY_CMPL */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE},
|
||||
/* REMT_NAME_EVT */ {BTA_DM_DISC_RMT_NAME, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE},
|
||||
/* SDP_RESULT_EVT */ {BTA_DM_SDP_RESULT, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE},
|
||||
/* SEARCH_CMPL_EVT */ {BTA_DM_SEARCH_CMPL, BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IDLE},
|
||||
/* DISCV_RES_EVT */ {BTA_DM_DISC_RESULT, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE},
|
||||
/* API_DI_DISCOVER_EVT */ {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE}
|
||||
|
||||
#if BLE_INCLUDED == TRUE
|
||||
/* DISC_CLOSE_TOUT_EVT */ , {BTA_DM_SEARCH_IGNORE, BTA_DM_SEARCH_IGNORE, BTA_DM_DISCOVER_ACTIVE}
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef const UINT8 (*tBTA_DM_ST_TBL)[BTA_DM_SEARCH_NUM_COLS];
|
||||
|
||||
/* state table */
|
||||
const tBTA_DM_ST_TBL bta_dm_search_st_tbl[] = {
|
||||
bta_dm_search_idle_st_table,
|
||||
bta_dm_search_search_active_st_table,
|
||||
bta_dm_search_search_cancelling_st_table,
|
||||
bta_dm_search_disc_active_st_table
|
||||
};
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sm_disable
|
||||
**
|
||||
** Description unregister BTA DM
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_dm_sm_disable( )
|
||||
{
|
||||
bta_sys_deregister( BTA_ID_DM );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sm_execute
|
||||
**
|
||||
** Description State machine event handling function for DM
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_dm_sm_execute(BT_HDR *p_msg)
|
||||
{
|
||||
UINT16 event = p_msg->event & 0x00ff;
|
||||
|
||||
APPL_TRACE_EVENT("bta_dm_sm_execute event:0x%x", event);
|
||||
|
||||
/* execute action functions */
|
||||
if (event < BTA_DM_NUM_ACTIONS) {
|
||||
(*bta_dm_action[event])( (tBTA_DM_MSG *) p_msg);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sm_search_disable
|
||||
**
|
||||
** Description unregister BTA SEARCH DM
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_dm_search_sm_disable( )
|
||||
{
|
||||
bta_sys_deregister( BTA_ID_DM_SEARCH );
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_search_sm_execute
|
||||
**
|
||||
** Description State machine event handling function for DM
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_dm_search_sm_execute(BT_HDR *p_msg)
|
||||
{
|
||||
tBTA_DM_ST_TBL state_table;
|
||||
UINT8 action;
|
||||
int i;
|
||||
|
||||
APPL_TRACE_EVENT("bta_dm_search_sm_execute state:%d, event:0x%x",
|
||||
bta_dm_search_cb.state, p_msg->event);
|
||||
|
||||
/* look up the state table for the current state */
|
||||
state_table = bta_dm_search_st_tbl[bta_dm_search_cb.state];
|
||||
|
||||
bta_dm_search_cb.state = state_table[p_msg->event & 0x00ff][BTA_DM_SEARCH_NEXT_STATE];
|
||||
|
||||
|
||||
/* execute action functions */
|
||||
for (i = 0; i < BTA_DM_SEARCH_ACTIONS; i++) {
|
||||
if ((action = state_table[p_msg->event & 0x00ff][i]) != BTA_DM_SEARCH_IGNORE) {
|
||||
(*bta_dm_search_action[action])( (tBTA_DM_MSG *) p_msg);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
1159
components/bt/bluedroid/bta/dm/bta_dm_pm.c
Normal file
1159
components/bt/bluedroid/bta/dm/bta_dm_pm.c
Normal file
File diff suppressed because it is too large
Load Diff
655
components/bt/bluedroid/bta/dm/bta_dm_sco.c
Normal file
655
components/bt/bluedroid/bta/dm/bta_dm_sco.c
Normal file
@@ -0,0 +1,655 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the down sampling utility to convert PCM samples in
|
||||
* 16k/32k/48k/44.1k/22050/11025 sampling rate into 8K/16bits samples
|
||||
* required for SCO channel format. One API function isprovided and only
|
||||
* possible to be used when transmitting SCO data is sent via HCI
|
||||
* interface.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include <string.h>
|
||||
#include "bta_api.h"
|
||||
#include "bta_sys.h"
|
||||
|
||||
#if (BTM_SCO_HCI_INCLUDED == TRUE)
|
||||
|
||||
#ifndef BTA_DM_SCO_DEBUG
|
||||
#define BTA_DM_SCO_DEBUG FALSE
|
||||
#endif
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
|
||||
#define BTA_DM_PCM_OVERLAP_SIZE 48
|
||||
|
||||
#define BTA_DM_PCM_SMPL_RATE_44100 44100
|
||||
#define BTA_DM_PCM_SMPL_RATE_22050 22050
|
||||
#define BTA_DM_PCM_SMPL_RATE_11025 11025
|
||||
|
||||
/*****************************************************************************
|
||||
** Data types for PCM Resampling utility
|
||||
*****************************************************************************/
|
||||
|
||||
typedef INT32 (*PCONVERT_TO_BT_FILTERED) (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
|
||||
UINT32 dwSrcSps, INT32 *pLastCurPos, UINT8 *pOverlapArea);
|
||||
typedef INT32 (*PCONVERT_TO_BT_NOFILTER) (void *pSrc, void *pDst, UINT32 dwSrcSamples,
|
||||
UINT32 dwSrcSps);
|
||||
typedef struct {
|
||||
UINT8 overlap_area[BTA_DM_PCM_OVERLAP_SIZE * 4];
|
||||
UINT32 cur_pos; /* current position */
|
||||
UINT32 src_sps; /* samples per second (source audio data) */
|
||||
PCONVERT_TO_BT_FILTERED filter; /* the action function to do the
|
||||
conversion 44100, 22050, 11025*/
|
||||
PCONVERT_TO_BT_NOFILTER nofilter; /* the action function to do
|
||||
the conversion 48000, 32000, 16000*/
|
||||
UINT32 bits; /* number of bits per pcm sample */
|
||||
UINT32 n_channels; /* number of channels (i.e. mono(1), stereo(2)...) */
|
||||
UINT32 sample_size;
|
||||
UINT32 can_be_filtered;
|
||||
UINT32 divisor;
|
||||
} tBTA_DM_PCM_RESAMPLE_CB;
|
||||
|
||||
tBTA_DM_PCM_RESAMPLE_CB bta_dm_pcm_cb;
|
||||
|
||||
/*****************************************************************************
|
||||
** Macro Definition
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#define CHECK_SATURATION16(x) \
|
||||
if (x > 32767) \
|
||||
x = 32767; \
|
||||
else if (x < -32768) \
|
||||
x = -32768;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
#define CONVERT_44100_TO_BLUETOOTH(pStart, pEnd) \
|
||||
{ \
|
||||
INT32 out1, out2, out3, out4, out5; \
|
||||
SRC_TYPE *pS = (SRC_TYPE *)pStart; \
|
||||
SRC_TYPE *pSEnd = (SRC_TYPE *)pEnd; \
|
||||
\
|
||||
while (pS < pSEnd) \
|
||||
{ \
|
||||
CurrentPos -= 8000; \
|
||||
\
|
||||
if (CurrentPos >= 0) \
|
||||
{ \
|
||||
pS += SRC_CHANNELS; \
|
||||
continue; \
|
||||
} \
|
||||
CurrentPos += dwSrcSps; \
|
||||
\
|
||||
out1 = (SRC_SAMPLE(0) * 1587) \
|
||||
+ ((SRC_SAMPLE(1) + SRC_SAMPLE(-1)) * 1522) \
|
||||
+ ((SRC_SAMPLE(2) + SRC_SAMPLE(-2)) * 1337) \
|
||||
+ ((SRC_SAMPLE(3) + SRC_SAMPLE(-3)) * 1058); \
|
||||
\
|
||||
out1 = out1 / 30000; \
|
||||
\
|
||||
out2 = ((SRC_SAMPLE(4) + SRC_SAMPLE(-4)) * 725) \
|
||||
+ ((SRC_SAMPLE(5) + SRC_SAMPLE(-5)) * 384) \
|
||||
+ ((SRC_SAMPLE(6) + SRC_SAMPLE(-6)) * 79); \
|
||||
\
|
||||
out2 = out2 / 30000; \
|
||||
\
|
||||
out3 = ((SRC_SAMPLE(7) + SRC_SAMPLE(-7)) * 156) \
|
||||
+ ((SRC_SAMPLE(8) + SRC_SAMPLE(-8)) * 298) \
|
||||
+ ((SRC_SAMPLE(9) + SRC_SAMPLE(-9)) * 345); \
|
||||
\
|
||||
out3 = out3 / 30000; \
|
||||
\
|
||||
out4 = ((SRC_SAMPLE(10) + SRC_SAMPLE(-10)) * 306) \
|
||||
+ ((SRC_SAMPLE(11) + SRC_SAMPLE(-11)) * 207) \
|
||||
+ ((SRC_SAMPLE(12) + SRC_SAMPLE(-12)) * 78); \
|
||||
\
|
||||
out4 = out4 / 30000; \
|
||||
\
|
||||
out5 = out1 + out2 - out3 - out4; \
|
||||
\
|
||||
CHECK_SATURATION16(out5); \
|
||||
*psBtOut++ = (INT16)out5; \
|
||||
\
|
||||
pS += SRC_CHANNELS; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
#define CONVERT_22050_TO_BLUETOOTH(pStart, pEnd) \
|
||||
{ \
|
||||
INT32 out1, out2, out3, out4, out5; \
|
||||
SRC_TYPE *pS = (SRC_TYPE *)pStart; \
|
||||
SRC_TYPE *pSEnd = (SRC_TYPE *)pEnd; \
|
||||
\
|
||||
while (pS < pSEnd) \
|
||||
{ \
|
||||
CurrentPos -= 8000; \
|
||||
\
|
||||
if (CurrentPos >= 0) \
|
||||
{ \
|
||||
pS += SRC_CHANNELS; \
|
||||
continue; \
|
||||
} \
|
||||
CurrentPos += dwSrcSps; \
|
||||
\
|
||||
out1 = (SRC_SAMPLE(0) * 2993) \
|
||||
+ ((SRC_SAMPLE(1) + SRC_SAMPLE(-1)) * 2568) \
|
||||
+ ((SRC_SAMPLE(2) + SRC_SAMPLE(-2)) * 1509) \
|
||||
+ ((SRC_SAMPLE(3) + SRC_SAMPLE(-3)) * 331); \
|
||||
\
|
||||
out1 = out1 / 30000; \
|
||||
\
|
||||
out2 = ((SRC_SAMPLE(4) + SRC_SAMPLE(-4)) * 454) \
|
||||
+ ((SRC_SAMPLE(5) + SRC_SAMPLE(-5)) * 620) \
|
||||
+ ((SRC_SAMPLE(6) + SRC_SAMPLE(-6)) * 305); \
|
||||
\
|
||||
out2 = out2 / 30000; \
|
||||
\
|
||||
out3 = ((SRC_SAMPLE(7) + SRC_SAMPLE(-7)) * 127) \
|
||||
+ ((SRC_SAMPLE(8) + SRC_SAMPLE(-8)) * 350) \
|
||||
+ ((SRC_SAMPLE(9) + SRC_SAMPLE(-9)) * 265) \
|
||||
+ ((SRC_SAMPLE(10) + SRC_SAMPLE(-10)) * 6); \
|
||||
\
|
||||
out3 = out3 / 30000; \
|
||||
\
|
||||
out4 = ((SRC_SAMPLE(11) + SRC_SAMPLE(-11)) * 201); \
|
||||
\
|
||||
out4 = out4 / 30000; \
|
||||
\
|
||||
out5 = out1 - out2 + out3 - out4; \
|
||||
\
|
||||
CHECK_SATURATION16(out5); \
|
||||
*psBtOut++ = (INT16)out5; \
|
||||
\
|
||||
pS += SRC_CHANNELS; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
#define CONVERT_11025_TO_BLUETOOTH(pStart, pEnd) \
|
||||
{ \
|
||||
INT32 out1; \
|
||||
SRC_TYPE *pS = (SRC_TYPE *)pStart; \
|
||||
SRC_TYPE *pSEnd = (SRC_TYPE *)pEnd; \
|
||||
\
|
||||
while (pS < pSEnd) \
|
||||
{ \
|
||||
CurrentPos -= 8000; \
|
||||
\
|
||||
if (CurrentPos >= 0) \
|
||||
{ \
|
||||
pS += SRC_CHANNELS; \
|
||||
continue; \
|
||||
} \
|
||||
CurrentPos += dwSrcSps; \
|
||||
\
|
||||
out1 = (SRC_SAMPLE(0) * 6349) \
|
||||
+ ((SRC_SAMPLE(1) + SRC_SAMPLE(-1)) * 2874) \
|
||||
- ((SRC_SAMPLE(2) + SRC_SAMPLE(-2)) * 1148) \
|
||||
- ((SRC_SAMPLE(3) + SRC_SAMPLE(-3)) * 287) \
|
||||
+ ((SRC_SAMPLE(4) + SRC_SAMPLE(-4)) * 675) \
|
||||
- ((SRC_SAMPLE(5) + SRC_SAMPLE(-5)) * 258) \
|
||||
- ((SRC_SAMPLE(6) + SRC_SAMPLE(-6)) * 206) \
|
||||
+ ((SRC_SAMPLE(7) + SRC_SAMPLE(-7)) * 266); \
|
||||
\
|
||||
out1 = out1 / 30000; \
|
||||
\
|
||||
CHECK_SATURATION16(out1); \
|
||||
*psBtOut++ = (INT16)out1; \
|
||||
\
|
||||
pS += SRC_CHANNELS; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
#undef SRC_CHANNELS
|
||||
#undef SRC_SAMPLE
|
||||
#undef SRC_TYPE
|
||||
|
||||
#define SRC_TYPE UINT8
|
||||
#define SRC_CHANNELS 1
|
||||
#define SRC_SAMPLE(x) ((pS[x] - 0x80) << 8)
|
||||
|
||||
/*****************************************************************************
|
||||
** Local Function
|
||||
*****************************************************************************/
|
||||
INT32 Convert_8M_ToBT_Filtered (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
|
||||
UINT32 dwSrcSps, INT32 *pLastCurPos, UINT8 *pOverlapArea)
|
||||
{
|
||||
INT32 CurrentPos = *pLastCurPos;
|
||||
SRC_TYPE *pIn, *pInEnd;
|
||||
SRC_TYPE *pOv, *pOvEnd;
|
||||
INT16 *psBtOut = (INT16 *)pDst;
|
||||
#if BTA_DM_SCO_DEBUG
|
||||
APPL_TRACE_DEBUG("Convert_8M_ToBT_Filtered, CurrentPos %d\n", CurrentPos);
|
||||
#endif
|
||||
memcpy (pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 2), pSrc, BTA_DM_PCM_OVERLAP_SIZE * 2);
|
||||
|
||||
pOv = (SRC_TYPE *)(pOverlapArea + BTA_DM_PCM_OVERLAP_SIZE);
|
||||
pOvEnd = (SRC_TYPE *)(pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 3));
|
||||
|
||||
pIn = (SRC_TYPE *)(pSrc + BTA_DM_PCM_OVERLAP_SIZE);
|
||||
pInEnd = (SRC_TYPE *)(pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - \
|
||||
BTA_DM_PCM_OVERLAP_SIZE);
|
||||
|
||||
if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_44100) {
|
||||
CONVERT_44100_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_44100_TO_BLUETOOTH(pIn, pInEnd);
|
||||
} else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_22050) {
|
||||
CONVERT_22050_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_22050_TO_BLUETOOTH(pIn, pInEnd);
|
||||
} else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_11025) {
|
||||
CONVERT_11025_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_11025_TO_BLUETOOTH(pIn, pInEnd);
|
||||
}
|
||||
|
||||
memcpy (pOverlapArea, pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - \
|
||||
(BTA_DM_PCM_OVERLAP_SIZE * 2), BTA_DM_PCM_OVERLAP_SIZE * 2);
|
||||
|
||||
*pLastCurPos = CurrentPos;
|
||||
|
||||
return (psBtOut - (INT16 *)pDst);
|
||||
}
|
||||
|
||||
INT32 Convert_8M_ToBT_NoFilter (void *pSrc, void *pDst, UINT32 dwSrcSamples, UINT32 dwSrcSps)
|
||||
{
|
||||
INT32 CurrentPos;
|
||||
UINT8 *pbSrc = (UINT8 *)pSrc;
|
||||
INT16 *psDst = (INT16 *)pDst;
|
||||
INT16 sWorker;
|
||||
|
||||
// start at dwSpsSrc / 2, decrement by 8000
|
||||
//
|
||||
CurrentPos = (dwSrcSps >> 1);
|
||||
|
||||
while (dwSrcSamples--) {
|
||||
CurrentPos -= 8000;
|
||||
|
||||
if (CurrentPos >= 0) {
|
||||
pbSrc++;
|
||||
} else {
|
||||
sWorker = *pbSrc++;
|
||||
sWorker -= 0x80;
|
||||
sWorker <<= 8;
|
||||
|
||||
*psDst++ = sWorker;
|
||||
|
||||
CurrentPos += dwSrcSps;
|
||||
}
|
||||
}
|
||||
|
||||
return (psDst - (INT16 *)pDst);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
#undef SRC_CHANNELS
|
||||
#undef SRC_SAMPLE
|
||||
#undef SRC_TYPE
|
||||
|
||||
#define SRC_TYPE INT16
|
||||
#define SRC_CHANNELS 1
|
||||
#define SRC_SAMPLE(x) pS[x]
|
||||
|
||||
INT32 Convert_16M_ToBT_Filtered (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
|
||||
UINT32 dwSrcSps, INT32 *pLastCurPos, UINT8 *pOverlapArea)
|
||||
{
|
||||
INT32 CurrentPos = *pLastCurPos;
|
||||
SRC_TYPE *pIn, *pInEnd;
|
||||
SRC_TYPE *pOv, *pOvEnd;
|
||||
INT16 *psBtOut = (INT16 *)pDst;
|
||||
|
||||
memcpy (pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 2), pSrc, BTA_DM_PCM_OVERLAP_SIZE * 2);
|
||||
|
||||
pOv = (SRC_TYPE *)(pOverlapArea + BTA_DM_PCM_OVERLAP_SIZE);
|
||||
pOvEnd = (SRC_TYPE *)(pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 3));
|
||||
|
||||
pIn = (SRC_TYPE *)(pSrc + BTA_DM_PCM_OVERLAP_SIZE);
|
||||
pInEnd = (SRC_TYPE *)(pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - BTA_DM_PCM_OVERLAP_SIZE);
|
||||
|
||||
if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_44100) {
|
||||
CONVERT_44100_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_44100_TO_BLUETOOTH(pIn, pInEnd);
|
||||
} else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_22050) {
|
||||
CONVERT_22050_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_22050_TO_BLUETOOTH(pIn, pInEnd);
|
||||
} else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_11025) {
|
||||
CONVERT_11025_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_11025_TO_BLUETOOTH(pIn, pInEnd);
|
||||
}
|
||||
|
||||
memcpy (pOverlapArea, pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - \
|
||||
(BTA_DM_PCM_OVERLAP_SIZE * 2), BTA_DM_PCM_OVERLAP_SIZE * 2);
|
||||
|
||||
*pLastCurPos = CurrentPos;
|
||||
|
||||
return (psBtOut - (INT16 *)pDst);
|
||||
}
|
||||
|
||||
INT32 Convert_16M_ToBT_NoFilter (void *pSrc, void *pDst, UINT32 dwSrcSamples, UINT32 dwSrcSps)
|
||||
{
|
||||
INT32 CurrentPos;
|
||||
INT16 *psSrc = (INT16 *)pSrc;
|
||||
INT16 *psDst = (INT16 *)pDst;
|
||||
|
||||
// start at dwSpsSrc / 2, decrement by 8000
|
||||
//
|
||||
CurrentPos = (dwSrcSps >> 1);
|
||||
|
||||
while (dwSrcSamples--) {
|
||||
CurrentPos -= 8000;
|
||||
|
||||
if (CurrentPos >= 0) {
|
||||
psSrc++;
|
||||
} else {
|
||||
*psDst++ = *psSrc++;
|
||||
|
||||
CurrentPos += dwSrcSps;
|
||||
}
|
||||
}
|
||||
|
||||
return (psDst - (INT16 *)pDst);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
#undef SRC_CHANNELS
|
||||
#undef SRC_SAMPLE
|
||||
#undef SRC_TYPE
|
||||
|
||||
#define SRC_TYPE UINT8
|
||||
#define SRC_CHANNELS 2
|
||||
#define SRC_SAMPLE(x) ((((pS[x * 2] - 0x80) << 8) + ((pS[(x * 2) + 1] - 0x80) << 8)) >> 1)
|
||||
|
||||
INT32 Convert_8S_ToBT_Filtered (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
|
||||
UINT32 dwSrcSps, INT32 *pLastCurPos, UINT8 *pOverlapArea)
|
||||
{
|
||||
INT32 CurrentPos = *pLastCurPos;
|
||||
SRC_TYPE *pIn, *pInEnd;
|
||||
SRC_TYPE *pOv, *pOvEnd;
|
||||
INT16 *psBtOut = (INT16 *)pDst;
|
||||
|
||||
#if BTA_DM_SCO_DEBUG
|
||||
APPL_TRACE_DEBUG("Convert_8S_ToBT_Filtered CurrentPos %d, SRC_TYPE %d, SRC_CHANNELS %d, \
|
||||
dwSrcSamples %d, dwSrcSps %d", CurrentPos, sizeof (SRC_TYPE), SRC_CHANNELS, \
|
||||
dwSrcSamples, dwSrcSps);
|
||||
#endif
|
||||
memcpy (pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 2), pSrc, BTA_DM_PCM_OVERLAP_SIZE * 2);
|
||||
|
||||
pOv = (SRC_TYPE *)(pOverlapArea + BTA_DM_PCM_OVERLAP_SIZE);
|
||||
pOvEnd = (SRC_TYPE *)(pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 3));
|
||||
|
||||
pIn = (SRC_TYPE *)(pSrc + BTA_DM_PCM_OVERLAP_SIZE);
|
||||
pInEnd = (SRC_TYPE *)(pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - BTA_DM_PCM_OVERLAP_SIZE);
|
||||
|
||||
if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_44100) {
|
||||
CONVERT_44100_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_44100_TO_BLUETOOTH(pIn, pInEnd);
|
||||
} else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_22050) {
|
||||
CONVERT_22050_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_22050_TO_BLUETOOTH(pIn, pInEnd);
|
||||
} else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_11025) {
|
||||
CONVERT_11025_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_11025_TO_BLUETOOTH(pIn, pInEnd);
|
||||
}
|
||||
|
||||
memcpy (pOverlapArea, pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - \
|
||||
(BTA_DM_PCM_OVERLAP_SIZE * 2), BTA_DM_PCM_OVERLAP_SIZE * 2);
|
||||
|
||||
*pLastCurPos = CurrentPos;
|
||||
|
||||
return (psBtOut - (INT16 *)pDst);
|
||||
}
|
||||
|
||||
INT32 Convert_8S_ToBT_NoFilter (void *pSrc, void *pDst, UINT32 dwSrcSamples, UINT32 dwSrcSps)
|
||||
{
|
||||
INT32 CurrentPos;
|
||||
UINT8 *pbSrc = (UINT8 *)pSrc;
|
||||
INT16 *psDst = (INT16 *)pDst;
|
||||
INT16 sWorker, sWorker2;
|
||||
|
||||
// start at dwSpsSrc / 2, decrement by 8000
|
||||
//
|
||||
CurrentPos = (dwSrcSps >> 1);
|
||||
|
||||
while (dwSrcSamples--) {
|
||||
CurrentPos -= 8000;
|
||||
|
||||
if (CurrentPos >= 0) {
|
||||
pbSrc += 2;
|
||||
} else {
|
||||
sWorker = *(unsigned char *)pbSrc;
|
||||
sWorker -= 0x80;
|
||||
sWorker <<= 8;
|
||||
pbSrc++;
|
||||
|
||||
sWorker2 = *(unsigned char *)pbSrc;
|
||||
sWorker2 -= 0x80;
|
||||
sWorker2 <<= 8;
|
||||
pbSrc++;
|
||||
|
||||
sWorker += sWorker2;
|
||||
sWorker >>= 1;
|
||||
|
||||
*psDst++ = sWorker;
|
||||
|
||||
CurrentPos += dwSrcSps;
|
||||
}
|
||||
}
|
||||
|
||||
return (psDst - (INT16 *)pDst);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
#undef SRC_CHANNELS
|
||||
#undef SRC_SAMPLE
|
||||
#undef SRC_TYPE
|
||||
|
||||
#define SRC_TYPE INT16
|
||||
#define SRC_CHANNELS 2
|
||||
#define SRC_SAMPLE(x) ((pS[x * 2] + pS[(x * 2) + 1]) >> 1)
|
||||
|
||||
INT32 Convert_16S_ToBT_Filtered (UINT8 *pSrc, void *pDst, UINT32 dwSrcSamples,
|
||||
UINT32 dwSrcSps, INT32 *pLastCurPos, UINT8 *pOverlapArea)
|
||||
{
|
||||
INT32 CurrentPos = *pLastCurPos;
|
||||
SRC_TYPE *pIn, *pInEnd;
|
||||
SRC_TYPE *pOv, *pOvEnd;
|
||||
INT16 *psBtOut = (INT16 *)pDst;
|
||||
|
||||
memcpy (pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 2), pSrc, BTA_DM_PCM_OVERLAP_SIZE * 2);
|
||||
|
||||
pOv = (SRC_TYPE *)(pOverlapArea + BTA_DM_PCM_OVERLAP_SIZE);
|
||||
pOvEnd = (SRC_TYPE *)(pOverlapArea + (BTA_DM_PCM_OVERLAP_SIZE * 3));
|
||||
|
||||
pIn = (SRC_TYPE *)(pSrc + BTA_DM_PCM_OVERLAP_SIZE);
|
||||
pInEnd = (SRC_TYPE *)(pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - BTA_DM_PCM_OVERLAP_SIZE);
|
||||
|
||||
if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_44100) {
|
||||
CONVERT_44100_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_44100_TO_BLUETOOTH(pIn, pInEnd);
|
||||
} else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_22050) {
|
||||
CONVERT_22050_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_22050_TO_BLUETOOTH(pIn, pInEnd);
|
||||
} else if (dwSrcSps == BTA_DM_PCM_SMPL_RATE_11025) {
|
||||
CONVERT_11025_TO_BLUETOOTH(pOv, pOvEnd);
|
||||
CONVERT_11025_TO_BLUETOOTH(pIn, pInEnd);
|
||||
}
|
||||
|
||||
memcpy (pOverlapArea, pSrc + (dwSrcSamples * SRC_CHANNELS * sizeof (SRC_TYPE)) - \
|
||||
(BTA_DM_PCM_OVERLAP_SIZE * 2), BTA_DM_PCM_OVERLAP_SIZE * 2);
|
||||
|
||||
*pLastCurPos = CurrentPos;
|
||||
|
||||
return (psBtOut - (INT16 *)pDst);
|
||||
}
|
||||
|
||||
INT32 Convert_16S_ToBT_NoFilter (void *pSrc, void *pDst, UINT32 dwSrcSamples, UINT32 dwSrcSps)
|
||||
{
|
||||
INT32 CurrentPos;
|
||||
INT16 *psSrc = (INT16 *)pSrc;
|
||||
INT16 *psDst = (INT16 *)pDst;
|
||||
INT16 sWorker;
|
||||
|
||||
// start at dwSpsSrc / 2, decrement by 8000
|
||||
//
|
||||
CurrentPos = (dwSrcSps >> 1);
|
||||
|
||||
while (dwSrcSamples--) {
|
||||
CurrentPos -= 8000;
|
||||
|
||||
if (CurrentPos >= 0) {
|
||||
psSrc += 2;
|
||||
} else {
|
||||
/* CR 82894, to avoid overflow, divide before add */
|
||||
sWorker = ((*psSrc) >> 1 );
|
||||
psSrc++;
|
||||
sWorker += ((*psSrc) >> 1 );
|
||||
psSrc++;
|
||||
|
||||
*psDst++ = sWorker;
|
||||
|
||||
CurrentPos += dwSrcSps;
|
||||
}
|
||||
}
|
||||
|
||||
return (psDst - (INT16 *)pDst);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_DmPcmInitSamples
|
||||
**
|
||||
** Description initialize the down sample converter.
|
||||
**
|
||||
** src_sps: original samples per second (source audio data)
|
||||
** (ex. 44100, 48000)
|
||||
** bits: number of bits per pcm sample (16)
|
||||
** n_channels: number of channels (i.e. mono(1), stereo(2)...)
|
||||
**
|
||||
** Returns none
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_DmPcmInitSamples (UINT32 src_sps, UINT32 bits, UINT32 n_channels)
|
||||
{
|
||||
tBTA_DM_PCM_RESAMPLE_CB *p_cb = &bta_dm_pcm_cb;
|
||||
|
||||
p_cb->cur_pos = src_sps / 2;
|
||||
p_cb->src_sps = src_sps;
|
||||
p_cb->bits = bits;
|
||||
p_cb->n_channels = n_channels;
|
||||
p_cb->sample_size = 2;
|
||||
p_cb->divisor = 2;
|
||||
|
||||
memset(p_cb->overlap_area, 0, sizeof(p_cb->overlap_area) );
|
||||
|
||||
if ((src_sps == BTA_DM_PCM_SMPL_RATE_44100) ||
|
||||
(src_sps == BTA_DM_PCM_SMPL_RATE_22050) ||
|
||||
(src_sps == BTA_DM_PCM_SMPL_RATE_11025)) {
|
||||
p_cb->can_be_filtered = 1;
|
||||
} else {
|
||||
p_cb->can_be_filtered = 0;
|
||||
}
|
||||
|
||||
#if BTA_DM_SCO_DEBUG
|
||||
APPL_TRACE_DEBUG("bta_dm_pcm_init_samples: n_channels = %d bits = %d", n_channels, bits);
|
||||
#endif
|
||||
if (n_channels == 1) {
|
||||
/* mono */
|
||||
if (bits == 8) {
|
||||
p_cb->filter = (PCONVERT_TO_BT_FILTERED) Convert_8M_ToBT_Filtered;
|
||||
p_cb->nofilter = (PCONVERT_TO_BT_NOFILTER) Convert_8M_ToBT_NoFilter;
|
||||
p_cb->divisor = 1;
|
||||
} else {
|
||||
p_cb->filter = (PCONVERT_TO_BT_FILTERED) Convert_16M_ToBT_Filtered;
|
||||
p_cb->nofilter = (PCONVERT_TO_BT_NOFILTER) Convert_16M_ToBT_NoFilter;
|
||||
}
|
||||
} else {
|
||||
/* stereo */
|
||||
if (bits == 8) {
|
||||
p_cb->filter = (PCONVERT_TO_BT_FILTERED) Convert_8S_ToBT_Filtered;
|
||||
p_cb->nofilter = (PCONVERT_TO_BT_NOFILTER) Convert_8S_ToBT_NoFilter;
|
||||
} else {
|
||||
p_cb->filter = (PCONVERT_TO_BT_FILTERED) Convert_16S_ToBT_Filtered;
|
||||
p_cb->nofilter = (PCONVERT_TO_BT_NOFILTER) Convert_16S_ToBT_NoFilter;
|
||||
p_cb->divisor = 4;
|
||||
}
|
||||
}
|
||||
|
||||
#if BTA_DM_SCO_DEBUG
|
||||
APPL_TRACE_DEBUG("bta_pcm_init_dwn_sample: cur_pos %d, src_sps %d", \
|
||||
p_cb->cur_pos, p_cb->src_sps);
|
||||
APPL_TRACE_DEBUG("bta_pcm_init_dwn_sample: bits %d, n_channels %d, sample_size %d, ", \
|
||||
p_cb->bits, p_cb->n_channels, p_cb->sample_size);
|
||||
APPL_TRACE_DEBUG("bta_pcm_init_dwn_sample: can_be_filtered %d, n_channels: %d, \
|
||||
divisor %d", p_cb->can_be_filtered, p_cb->n_channels, p_cb->divisor);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/**************************************************************************************
|
||||
** Function BTA_DmPcmResample
|
||||
**
|
||||
** Description Down sampling utility to convert higher sampling rate into 8K/16bits
|
||||
** PCM samples.
|
||||
**
|
||||
** Parameters p_src: pointer to the buffer where the original sampling PCM
|
||||
** are stored.
|
||||
** in_bytes: Length of the input PCM sample buffer in byte.
|
||||
** p_dst: pointer to the buffer which is to be used to store
|
||||
** the converted PCM samples.
|
||||
**
|
||||
**
|
||||
** Returns INT32: number of samples converted.
|
||||
**
|
||||
**************************************************************************************/
|
||||
INT32 BTA_DmPcmResample (void *p_src, UINT32 in_bytes, void *p_dst)
|
||||
{
|
||||
UINT32 out_sample;
|
||||
|
||||
#if BTA_DM_SCO_DEBUG
|
||||
APPL_TRACE_DEBUG("bta_pcm_resample : insamples %d", (in_bytes / bta_dm_pcm_cb.divisor));
|
||||
#endif
|
||||
if (bta_dm_pcm_cb.can_be_filtered) {
|
||||
out_sample = (*bta_dm_pcm_cb.filter) (p_src, p_dst, (in_bytes / bta_dm_pcm_cb.divisor),
|
||||
bta_dm_pcm_cb.src_sps, (INT32 *) &bta_dm_pcm_cb.cur_pos, bta_dm_pcm_cb.overlap_area);
|
||||
} else {
|
||||
out_sample = (*bta_dm_pcm_cb.nofilter) (p_src, p_dst,
|
||||
(in_bytes / bta_dm_pcm_cb.divisor), bta_dm_pcm_cb.src_sps);
|
||||
}
|
||||
|
||||
#if BTA_DM_SCO_DEBUG
|
||||
APPL_TRACE_DEBUG("bta_pcm_resample : outsamples %d", out_sample);
|
||||
#endif
|
||||
|
||||
return (out_sample * bta_dm_pcm_cb.sample_size);
|
||||
}
|
||||
#endif
|
||||
2202
components/bt/bluedroid/bta/gatt/bta_gattc_act.c
Normal file
2202
components/bt/bluedroid/bta/gatt/bta_gattc_act.c
Normal file
File diff suppressed because it is too large
Load Diff
1062
components/bt/bluedroid/bta/gatt/bta_gattc_api.c
Normal file
1062
components/bt/bluedroid/bta/gatt/bta_gattc_api.c
Normal file
File diff suppressed because it is too large
Load Diff
1508
components/bt/bluedroid/bta/gatt/bta_gattc_cache.c
Normal file
1508
components/bt/bluedroid/bta/gatt/bta_gattc_cache.c
Normal file
File diff suppressed because it is too large
Load Diff
136
components/bt/bluedroid/bta/gatt/bta_gattc_ci.c
Normal file
136
components/bt/bluedroid/bta/gatt/bta_gattc_ci.c
Normal file
@@ -0,0 +1,136 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the implementation file for the GATT call-in functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
|
||||
#if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "bta_api.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_gattc_ci.h"
|
||||
#include "gki.h"
|
||||
#include "utl.h"
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_ci_cache_open
|
||||
**
|
||||
** Description This function sends an event to indicate server cache open
|
||||
** completed.
|
||||
**
|
||||
** Parameters server_bda - server BDA of this cache.
|
||||
** status - BTA_GATT_OK if full buffer of data,
|
||||
** BTA_GATT_FAIL if an error has occurred.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gattc_ci_cache_open(BD_ADDR server_bda, UINT16 evt, tBTA_GATT_STATUS status,
|
||||
UINT16 conn_id)
|
||||
{
|
||||
tBTA_GATTC_CI_EVT *p_evt;
|
||||
UNUSED(server_bda);
|
||||
|
||||
if ((p_evt = (tBTA_GATTC_CI_EVT *) GKI_getbuf(sizeof(tBTA_GATTC_CI_EVT))) != NULL) {
|
||||
p_evt->hdr.event = evt;
|
||||
p_evt->hdr.layer_specific = conn_id;
|
||||
|
||||
p_evt->status = status;
|
||||
bta_sys_sendmsg(p_evt);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_ci_cache_load
|
||||
**
|
||||
** Description This function sends an event to BTA indicating the phone has
|
||||
** load the servere cache and ready to send it to the stack.
|
||||
**
|
||||
** Parameters server_bda - server BDA of this cache.
|
||||
** num_bytes_read - number of bytes read into the buffer
|
||||
** specified in the read callout-function.
|
||||
** status - BTA_GATT_OK if full buffer of data,
|
||||
** BTA_GATT_FAIL if an error has occurred.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gattc_ci_cache_load(BD_ADDR server_bda, UINT16 evt, UINT16 num_attr,
|
||||
tBTA_GATTC_NV_ATTR *p_attr, tBTA_GATT_STATUS status,
|
||||
UINT16 conn_id)
|
||||
{
|
||||
tBTA_GATTC_CI_LOAD *p_evt;
|
||||
UNUSED(server_bda);
|
||||
|
||||
if ((p_evt = (tBTA_GATTC_CI_LOAD *) GKI_getbuf(sizeof(tBTA_GATTC_CI_LOAD))) != NULL) {
|
||||
memset(p_evt, 0, sizeof(tBTA_GATTC_CI_LOAD));
|
||||
|
||||
p_evt->hdr.event = evt;
|
||||
p_evt->hdr.layer_specific = conn_id;
|
||||
|
||||
p_evt->status = status;
|
||||
p_evt->num_attr = (num_attr > BTA_GATTC_NV_LOAD_MAX) ? BTA_GATTC_NV_LOAD_MAX : num_attr;
|
||||
|
||||
if (p_evt->num_attr > 0 && p_attr != NULL) {
|
||||
memcpy(p_evt->attr, p_attr, p_evt->num_attr * sizeof(tBTA_GATTC_NV_ATTR));
|
||||
}
|
||||
|
||||
bta_sys_sendmsg(p_evt);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_ci_cache_save
|
||||
**
|
||||
** Description This function sends an event to BTA indicating the phone has
|
||||
** save the servere cache.
|
||||
**
|
||||
** Parameters server_bda - server BDA of this cache.
|
||||
** evt - callin event code.
|
||||
** status - BTA_GATT_OK if full buffer of data,
|
||||
** BTA_GATT_ERROR if an error has occurred.
|
||||
*8 conn_id - for this NV operation for.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gattc_ci_cache_save(BD_ADDR server_bda, UINT16 evt, tBTA_GATT_STATUS status,
|
||||
UINT16 conn_id)
|
||||
{
|
||||
tBTA_GATTC_CI_EVT *p_evt;
|
||||
UNUSED(server_bda);
|
||||
|
||||
if ((p_evt = (tBTA_GATTC_CI_EVT *) GKI_getbuf(sizeof(tBTA_GATTC_CI_EVT))) != NULL) {
|
||||
p_evt->hdr.event = evt;
|
||||
p_evt->hdr.layer_specific = conn_id;
|
||||
|
||||
p_evt->status = status;
|
||||
bta_sys_sendmsg(p_evt);
|
||||
}
|
||||
}
|
||||
#endif /* BTA_GATT_INCLUDED */
|
||||
525
components/bt/bluedroid/bta/gatt/bta_gattc_main.c
Normal file
525
components/bt/bluedroid/bta/gatt/bta_gattc_main.c
Normal file
@@ -0,0 +1,525 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the GATT client main functions and state machine.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
|
||||
#if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "bta_gattc_int.h"
|
||||
#include "gki.h"
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and types
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/* state machine action enumeration list */
|
||||
enum {
|
||||
BTA_GATTC_OPEN,
|
||||
BTA_GATTC_OPEN_FAIL,
|
||||
BTA_GATTC_OPEN_ERROR,
|
||||
BTA_GATTC_CANCEL_OPEN,
|
||||
BTA_GATTC_CANCEL_OPEN_OK,
|
||||
BTA_GATTC_CANCEL_OPEN_ERROR,
|
||||
BTA_GATTC_CONN,
|
||||
BTA_GATTC_START_DISCOVER,
|
||||
BTA_GATTC_DISC_CMPL,
|
||||
|
||||
BTA_GATTC_Q_CMD,
|
||||
BTA_GATTC_CLOSE,
|
||||
BTA_GATTC_CLOSE_FAIL,
|
||||
BTA_GATTC_READ,
|
||||
BTA_GATTC_WRITE,
|
||||
|
||||
BTA_GATTC_OP_CMPL,
|
||||
BTA_GATTC_SEARCH,
|
||||
BTA_GATTC_FAIL,
|
||||
BTA_GATTC_CONFIRM,
|
||||
BTA_GATTC_EXEC,
|
||||
BTA_GATTC_READ_MULTI,
|
||||
BTA_GATTC_CI_OPEN,
|
||||
BTA_GATTC_CI_LOAD,
|
||||
BTA_GATTC_CI_SAVE,
|
||||
BTA_GATTC_CACHE_OPEN,
|
||||
BTA_GATTC_IGNORE_OP_CMPL,
|
||||
BTA_GATTC_DISC_CLOSE,
|
||||
BTA_GATTC_RESTART_DISCOVER,
|
||||
BTA_GATTC_CFG_MTU,
|
||||
|
||||
BTA_GATTC_IGNORE
|
||||
};
|
||||
/* type for action functions */
|
||||
typedef void (*tBTA_GATTC_ACTION)(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
|
||||
/* action function list */
|
||||
const tBTA_GATTC_ACTION bta_gattc_action[] = {
|
||||
bta_gattc_open,
|
||||
bta_gattc_open_fail,
|
||||
bta_gattc_open_error,
|
||||
bta_gattc_cancel_open,
|
||||
bta_gattc_cancel_open_ok,
|
||||
bta_gattc_cancel_open_error,
|
||||
bta_gattc_conn,
|
||||
bta_gattc_start_discover,
|
||||
bta_gattc_disc_cmpl,
|
||||
|
||||
bta_gattc_q_cmd,
|
||||
bta_gattc_close,
|
||||
bta_gattc_close_fail,
|
||||
bta_gattc_read,
|
||||
bta_gattc_write,
|
||||
|
||||
bta_gattc_op_cmpl,
|
||||
bta_gattc_search,
|
||||
bta_gattc_fail,
|
||||
bta_gattc_confirm,
|
||||
bta_gattc_execute,
|
||||
bta_gattc_read_multi,
|
||||
bta_gattc_ci_open,
|
||||
bta_gattc_ci_load,
|
||||
bta_gattc_ci_save,
|
||||
bta_gattc_cache_open,
|
||||
bta_gattc_ignore_op_cmpl,
|
||||
bta_gattc_disc_close,
|
||||
bta_gattc_restart_discover,
|
||||
bta_gattc_cfg_mtu
|
||||
};
|
||||
|
||||
|
||||
/* state table information */
|
||||
#define BTA_GATTC_ACTIONS 1 /* number of actions */
|
||||
#define BTA_GATTC_NEXT_STATE 1 /* position of next state */
|
||||
#define BTA_GATTC_NUM_COLS 2 /* number of columns in state tables */
|
||||
|
||||
/* state table for idle state */
|
||||
static const UINT8 bta_gattc_st_idle[][BTA_GATTC_NUM_COLS] = {
|
||||
/* Event Action 1 Next state */
|
||||
/* BTA_GATTC_API_OPEN_EVT */ {BTA_GATTC_OPEN, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_INT_OPEN_FAIL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_API_CANCEL_OPEN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_INT_CANCEL_OPEN_OK_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
|
||||
/* BTA_GATTC_API_READ_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_API_WRITE_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_API_EXEC_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_API_CFG_MTU_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
|
||||
/* BTA_GATTC_API_CLOSE_EVT */ {BTA_GATTC_CLOSE_FAIL, BTA_GATTC_IDLE_ST},
|
||||
|
||||
/* BTA_GATTC_API_SEARCH_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_API_CONFIRM_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_API_READ_MULTI_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_API_REFRESH_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
|
||||
/* BTA_GATTC_INT_CONN_EVT */ {BTA_GATTC_CONN, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_INT_DISCOVER_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_DISCOVER_CMPL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_OP_CMPL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
|
||||
|
||||
/* ===> for cache loading, saving */
|
||||
/* BTA_GATTC_START_CACHE_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_CI_CACHE_OPEN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_CI_CACHE_LOAD_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_CI_CACHE_SAVE_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_IDLE_ST}
|
||||
};
|
||||
|
||||
/* state table for wait for open state */
|
||||
static const UINT8 bta_gattc_st_w4_conn[][BTA_GATTC_NUM_COLS] = {
|
||||
/* Event Action 1 Next state */
|
||||
/* BTA_GATTC_API_OPEN_EVT */ {BTA_GATTC_OPEN, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_INT_OPEN_FAIL_EVT */ {BTA_GATTC_OPEN_FAIL, BTA_GATTC_IDLE_ST},
|
||||
/* BTA_GATTC_API_CANCEL_OPEN_EVT */ {BTA_GATTC_CANCEL_OPEN, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_INT_CANCEL_OPEN_OK_EVT */ {BTA_GATTC_CANCEL_OPEN_OK, BTA_GATTC_IDLE_ST},
|
||||
|
||||
/* BTA_GATTC_API_READ_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_API_WRITE_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_API_EXEC_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_API_CFG_MTU_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
|
||||
|
||||
/* BTA_GATTC_API_CLOSE_EVT */ {BTA_GATTC_CANCEL_OPEN, BTA_GATTC_W4_CONN_ST},
|
||||
|
||||
/* BTA_GATTC_API_SEARCH_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_API_CONFIRM_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_API_READ_MULTI_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_API_REFRESH_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
|
||||
|
||||
/* BTA_GATTC_INT_CONN_EVT */ {BTA_GATTC_CONN, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_INT_DISCOVER_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_DISCOVER_CMPL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_OP_CMPL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_OPEN_FAIL, BTA_GATTC_IDLE_ST},
|
||||
|
||||
/* ===> for cache loading, saving */
|
||||
/* BTA_GATTC_START_CACHE_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_CI_CACHE_OPEN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_CI_CACHE_LOAD_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST},
|
||||
/* BTA_GATTC_CI_CACHE_SAVE_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_W4_CONN_ST}
|
||||
};
|
||||
|
||||
/* state table for open state */
|
||||
static const UINT8 bta_gattc_st_connected[][BTA_GATTC_NUM_COLS] = {
|
||||
/* Event Action 1 Next state */
|
||||
/* BTA_GATTC_API_OPEN_EVT */ {BTA_GATTC_OPEN, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_INT_OPEN_FAIL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_API_CANCEL_OPEN_EVT */ {BTA_GATTC_CANCEL_OPEN_ERROR, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_INT_CANCEL_OPEN_OK_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_CONN_ST},
|
||||
|
||||
/* BTA_GATTC_API_READ_EVT */ {BTA_GATTC_READ, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_API_WRITE_EVT */ {BTA_GATTC_WRITE, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_API_EXEC_EVT */ {BTA_GATTC_EXEC, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_API_CFG_MTU_EVT */ {BTA_GATTC_CFG_MTU, BTA_GATTC_CONN_ST},
|
||||
|
||||
/* BTA_GATTC_API_CLOSE_EVT */ {BTA_GATTC_CLOSE, BTA_GATTC_IDLE_ST},
|
||||
|
||||
/* BTA_GATTC_API_SEARCH_EVT */ {BTA_GATTC_SEARCH, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_API_CONFIRM_EVT */ {BTA_GATTC_CONFIRM, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_API_READ_MULTI_EVT */ {BTA_GATTC_READ_MULTI, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_API_REFRESH_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_CONN_ST},
|
||||
|
||||
/* BTA_GATTC_INT_CONN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_INT_DISCOVER_EVT */ {BTA_GATTC_START_DISCOVER, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_DISCOVER_CMPL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_OP_CMPL_EVT */ {BTA_GATTC_OP_CMPL, BTA_GATTC_CONN_ST},
|
||||
|
||||
/* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_CLOSE, BTA_GATTC_IDLE_ST},
|
||||
|
||||
/* ===> for cache loading, saving */
|
||||
/* BTA_GATTC_START_CACHE_EVT */ {BTA_GATTC_CACHE_OPEN, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_CI_CACHE_OPEN_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_CI_CACHE_LOAD_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_CI_CACHE_SAVE_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_CONN_ST}
|
||||
};
|
||||
|
||||
/* state table for discover state */
|
||||
static const UINT8 bta_gattc_st_discover[][BTA_GATTC_NUM_COLS] = {
|
||||
/* Event Action 1 Next state */
|
||||
/* BTA_GATTC_API_OPEN_EVT */ {BTA_GATTC_OPEN, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_INT_OPEN_FAIL_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_API_CANCEL_OPEN_EVT */ {BTA_GATTC_CANCEL_OPEN_ERROR, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_INT_CANCEL_OPEN_OK_EVT */ {BTA_GATTC_FAIL, BTA_GATTC_DISCOVER_ST},
|
||||
|
||||
/* BTA_GATTC_API_READ_EVT */ {BTA_GATTC_Q_CMD, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_API_WRITE_EVT */ {BTA_GATTC_Q_CMD, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_API_EXEC_EVT */ {BTA_GATTC_Q_CMD, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_API_CFG_MTU_EVT */ {BTA_GATTC_Q_CMD, BTA_GATTC_DISCOVER_ST},
|
||||
|
||||
/* BTA_GATTC_API_CLOSE_EVT */ {BTA_GATTC_DISC_CLOSE, BTA_GATTC_DISCOVER_ST},
|
||||
|
||||
/* BTA_GATTC_API_SEARCH_EVT */ {BTA_GATTC_Q_CMD, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_API_CONFIRM_EVT */ {BTA_GATTC_CONFIRM, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_API_READ_MULTI_EVT */ {BTA_GATTC_Q_CMD, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_API_REFRESH_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_DISCOVER_ST},
|
||||
|
||||
/* BTA_GATTC_INT_CONN_EVT */ {BTA_GATTC_CONN, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_INT_DISCOVER_EVT */ {BTA_GATTC_RESTART_DISCOVER, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_DISCOVER_CMPL_EVT */ {BTA_GATTC_DISC_CMPL, BTA_GATTC_CONN_ST},
|
||||
/* BTA_GATTC_OP_CMPL_EVT */ {BTA_GATTC_IGNORE_OP_CMPL, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_INT_DISCONN_EVT */ {BTA_GATTC_CLOSE, BTA_GATTC_IDLE_ST},
|
||||
|
||||
/* ===> for cache loading, saving */
|
||||
/* BTA_GATTC_START_CACHE_EVT */ {BTA_GATTC_IGNORE, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_CI_CACHE_OPEN_EVT */ {BTA_GATTC_CI_OPEN, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_CI_CACHE_LOAD_EVT */ {BTA_GATTC_CI_LOAD, BTA_GATTC_DISCOVER_ST},
|
||||
/* BTA_GATTC_CI_CACHE_SAVE_EVT */ {BTA_GATTC_CI_SAVE, BTA_GATTC_DISCOVER_ST}
|
||||
};
|
||||
|
||||
/* type for state table */
|
||||
typedef const UINT8 (*tBTA_GATTC_ST_TBL)[BTA_GATTC_NUM_COLS];
|
||||
|
||||
/* state table */
|
||||
const tBTA_GATTC_ST_TBL bta_gattc_st_tbl[] = {
|
||||
bta_gattc_st_idle,
|
||||
bta_gattc_st_w4_conn,
|
||||
bta_gattc_st_connected,
|
||||
bta_gattc_st_discover
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
** Global data
|
||||
*****************************************************************************/
|
||||
|
||||
/* GATTC control block */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
tBTA_GATTC_CB bta_gattc_cb;
|
||||
#endif
|
||||
|
||||
#if BTA_GATT_DEBUG == TRUE
|
||||
static char *gattc_evt_code(tBTA_GATTC_INT_EVT evt_code);
|
||||
static char *gattc_state_code(tBTA_GATTC_STATE state_code);
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_sm_execute
|
||||
**
|
||||
** Description State machine event handling function for GATTC
|
||||
**
|
||||
**
|
||||
** Returns BOOLEAN : TRUE if queued client request buffer can be immediately released
|
||||
** else FALSE
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data)
|
||||
{
|
||||
tBTA_GATTC_ST_TBL state_table;
|
||||
UINT8 action;
|
||||
int i;
|
||||
BOOLEAN rt = TRUE;
|
||||
#if BTA_GATT_DEBUG == TRUE
|
||||
tBTA_GATTC_STATE in_state = p_clcb->state;
|
||||
UINT16 in_event = event;
|
||||
APPL_TRACE_DEBUG("bta_gattc_sm_execute: State 0x%02x [%s], Event 0x%x[%s]", in_state,
|
||||
gattc_state_code(in_state),
|
||||
in_event,
|
||||
gattc_evt_code(in_event));
|
||||
#endif
|
||||
|
||||
|
||||
/* look up the state table for the current state */
|
||||
state_table = bta_gattc_st_tbl[p_clcb->state];
|
||||
|
||||
event &= 0x00FF;
|
||||
|
||||
/* set next state */
|
||||
p_clcb->state = state_table[event][BTA_GATTC_NEXT_STATE];
|
||||
|
||||
/* execute action functions */
|
||||
for (i = 0; i < BTA_GATTC_ACTIONS; i++) {
|
||||
if ((action = state_table[event][i]) != BTA_GATTC_IGNORE) {
|
||||
(*bta_gattc_action[action])(p_clcb, p_data);
|
||||
if (p_clcb->p_q_cmd == p_data) {
|
||||
/* buffer is queued, don't free in the bta dispatcher.
|
||||
* we free it ourselves when a completion event is received.
|
||||
*/
|
||||
rt = FALSE;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if BTA_GATT_DEBUG == TRUE
|
||||
if (in_state != p_clcb->state) {
|
||||
APPL_TRACE_DEBUG("GATTC State Change: [%s] -> [%s] after Event [%s]",
|
||||
gattc_state_code(in_state),
|
||||
gattc_state_code(p_clcb->state),
|
||||
gattc_evt_code(in_event));
|
||||
}
|
||||
#endif
|
||||
return rt;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_hdl_event
|
||||
**
|
||||
** Description GATT client main event handling function.
|
||||
**
|
||||
**
|
||||
** Returns BOOLEAN
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg)
|
||||
{
|
||||
tBTA_GATTC_CB *p_cb = &bta_gattc_cb;
|
||||
tBTA_GATTC_CLCB *p_clcb = NULL;
|
||||
tBTA_GATTC_RCB *p_clreg;
|
||||
BOOLEAN rt = TRUE;
|
||||
#if BTA_GATT_DEBUG == TRUE
|
||||
APPL_TRACE_DEBUG("bta_gattc_hdl_event: Event [%s]\n", gattc_evt_code(p_msg->event));
|
||||
#endif
|
||||
switch (p_msg->event) {
|
||||
case BTA_GATTC_API_DISABLE_EVT:
|
||||
bta_gattc_disable(p_cb);
|
||||
break;
|
||||
|
||||
case BTA_GATTC_API_REG_EVT:
|
||||
bta_gattc_register(p_cb, (tBTA_GATTC_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTC_INT_START_IF_EVT:
|
||||
bta_gattc_start_if(p_cb, (tBTA_GATTC_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTC_API_DEREG_EVT:
|
||||
p_clreg = bta_gattc_cl_get_regcb(((tBTA_GATTC_DATA *)p_msg)->api_dereg.client_if);
|
||||
bta_gattc_deregister(p_cb, p_clreg);
|
||||
break;
|
||||
|
||||
case BTA_GATTC_API_OPEN_EVT:
|
||||
bta_gattc_process_api_open(p_cb, (tBTA_GATTC_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTC_API_CANCEL_OPEN_EVT:
|
||||
bta_gattc_process_api_open_cancel(p_cb, (tBTA_GATTC_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTC_API_REFRESH_EVT:
|
||||
bta_gattc_process_api_refresh(p_cb, (tBTA_GATTC_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
#if BLE_INCLUDED == TRUE
|
||||
case BTA_GATTC_API_LISTEN_EVT:
|
||||
bta_gattc_listen(p_cb, (tBTA_GATTC_DATA *) p_msg);
|
||||
break;
|
||||
case BTA_GATTC_API_BROADCAST_EVT:
|
||||
bta_gattc_broadcast(p_cb, (tBTA_GATTC_DATA *) p_msg);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case BTA_GATTC_ENC_CMPL_EVT:
|
||||
bta_gattc_process_enc_cmpl(p_cb, (tBTA_GATTC_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (p_msg->event == BTA_GATTC_INT_CONN_EVT) {
|
||||
p_clcb = bta_gattc_find_int_conn_clcb((tBTA_GATTC_DATA *) p_msg);
|
||||
} else if (p_msg->event == BTA_GATTC_INT_DISCONN_EVT) {
|
||||
p_clcb = bta_gattc_find_int_disconn_clcb((tBTA_GATTC_DATA *) p_msg);
|
||||
} else {
|
||||
p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->layer_specific);
|
||||
}
|
||||
|
||||
if (p_clcb != NULL) {
|
||||
rt = bta_gattc_sm_execute(p_clcb, p_msg->event, (tBTA_GATTC_DATA *) p_msg);
|
||||
} else {
|
||||
APPL_TRACE_DEBUG("Ignore unknown conn ID: %d\n", p_msg->layer_specific);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Debug Functions
|
||||
*****************************************************************************/
|
||||
#if BTA_GATT_DEBUG == TRUE
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function gattc_evt_code
|
||||
**
|
||||
** Description
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static char *gattc_evt_code(tBTA_GATTC_INT_EVT evt_code)
|
||||
{
|
||||
switch (evt_code) {
|
||||
case BTA_GATTC_API_OPEN_EVT:
|
||||
return "BTA_GATTC_API_OPEN_EVT";
|
||||
case BTA_GATTC_INT_OPEN_FAIL_EVT:
|
||||
return "BTA_GATTC_INT_OPEN_FAIL_EVT";
|
||||
case BTA_GATTC_API_CANCEL_OPEN_EVT:
|
||||
return "BTA_GATTC_API_CANCEL_OPEN_EVT";
|
||||
case BTA_GATTC_INT_CANCEL_OPEN_OK_EVT:
|
||||
return "BTA_GATTC_INT_CANCEL_OPEN_OK_EVT";
|
||||
case BTA_GATTC_API_READ_EVT:
|
||||
return "BTA_GATTC_API_READ_EVT";
|
||||
case BTA_GATTC_API_WRITE_EVT:
|
||||
return "BTA_GATTC_API_WRITE_EVT";
|
||||
case BTA_GATTC_API_EXEC_EVT:
|
||||
return "BTA_GATTC_API_EXEC_EVT";
|
||||
case BTA_GATTC_API_CLOSE_EVT:
|
||||
return "BTA_GATTC_API_CLOSE_EVT";
|
||||
case BTA_GATTC_API_SEARCH_EVT:
|
||||
return "BTA_GATTC_API_SEARCH_EVT";
|
||||
case BTA_GATTC_API_CONFIRM_EVT:
|
||||
return "BTA_GATTC_API_CONFIRM_EVT";
|
||||
case BTA_GATTC_API_READ_MULTI_EVT:
|
||||
return "BTA_GATTC_API_READ_MULTI_EVT";
|
||||
case BTA_GATTC_INT_CONN_EVT:
|
||||
return "BTA_GATTC_INT_CONN_EVT";
|
||||
case BTA_GATTC_INT_DISCOVER_EVT:
|
||||
return "BTA_GATTC_INT_DISCOVER_EVT";
|
||||
case BTA_GATTC_DISCOVER_CMPL_EVT:
|
||||
return "BTA_GATTC_DISCOVER_CMPL_EVT";
|
||||
case BTA_GATTC_OP_CMPL_EVT:
|
||||
return "BTA_GATTC_OP_CMPL_EVT";
|
||||
case BTA_GATTC_INT_DISCONN_EVT:
|
||||
return "BTA_GATTC_INT_DISCONN_EVT";
|
||||
case BTA_GATTC_START_CACHE_EVT:
|
||||
return "BTA_GATTC_START_CACHE_EVT";
|
||||
case BTA_GATTC_CI_CACHE_OPEN_EVT:
|
||||
return "BTA_GATTC_CI_CACHE_OPEN_EVT";
|
||||
case BTA_GATTC_CI_CACHE_LOAD_EVT:
|
||||
return "BTA_GATTC_CI_CACHE_LOAD_EVT";
|
||||
case BTA_GATTC_CI_CACHE_SAVE_EVT:
|
||||
return "BTA_GATTC_CI_CACHE_SAVE_EVT";
|
||||
case BTA_GATTC_INT_START_IF_EVT:
|
||||
return "BTA_GATTC_INT_START_IF_EVT";
|
||||
case BTA_GATTC_API_REG_EVT:
|
||||
return "BTA_GATTC_API_REG_EVT";
|
||||
case BTA_GATTC_API_DEREG_EVT:
|
||||
return "BTA_GATTC_API_DEREG_EVT";
|
||||
case BTA_GATTC_API_REFRESH_EVT:
|
||||
return "BTA_GATTC_API_REFRESH_EVT";
|
||||
case BTA_GATTC_API_LISTEN_EVT:
|
||||
return "BTA_GATTC_API_LISTEN_EVT";
|
||||
case BTA_GATTC_API_DISABLE_EVT:
|
||||
return "BTA_GATTC_API_DISABLE_EVT";
|
||||
case BTA_GATTC_API_CFG_MTU_EVT:
|
||||
return "BTA_GATTC_API_CFG_MTU_EVT";
|
||||
default:
|
||||
return "unknown GATTC event code";
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function gattc_state_code
|
||||
**
|
||||
** Description
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static char *gattc_state_code(tBTA_GATTC_STATE state_code)
|
||||
{
|
||||
switch (state_code) {
|
||||
case BTA_GATTC_IDLE_ST:
|
||||
return "GATTC_IDLE_ST";
|
||||
case BTA_GATTC_W4_CONN_ST:
|
||||
return "GATTC_W4_CONN_ST";
|
||||
case BTA_GATTC_CONN_ST:
|
||||
return "GATTC_CONN_ST";
|
||||
case BTA_GATTC_DISCOVER_ST:
|
||||
return "GATTC_DISCOVER_ST";
|
||||
default:
|
||||
return "unknown GATTC state code";
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Debug Functions */
|
||||
#endif /* BTA_GATT_INCLUDED */
|
||||
928
components/bt/bluedroid/bta/gatt/bta_gattc_utils.c
Normal file
928
components/bt/bluedroid/bta/gatt/bta_gattc_utils.c
Normal file
@@ -0,0 +1,928 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the GATT client utility function.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
|
||||
#if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "bdaddr.h"
|
||||
// #include "btif/include/btif_util.h"
|
||||
#include "gki.h"
|
||||
#include "utl.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_gattc_int.h"
|
||||
#include "l2c_api.h"
|
||||
|
||||
#define LOG_TAG "bt_bta_gattc"
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
static const UINT8 base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
|
||||
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static const BD_ADDR dummy_bda = {0, 0, 0, 0, 0, 0};
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatt_convert_uuid16_to_uuid128
|
||||
**
|
||||
** Description Convert a 16 bits UUID to be an standard 128 bits one.
|
||||
**
|
||||
** Returns TRUE if two uuid match; FALSE otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16)
|
||||
{
|
||||
UINT8 *p = &uuid_128[LEN_UUID_128 - 4];
|
||||
|
||||
memcpy (uuid_128, base_uuid, LEN_UUID_128);
|
||||
|
||||
UINT16_TO_STREAM(p, uuid_16);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_uuid_compare
|
||||
**
|
||||
** Description Compare two UUID to see if they are the same.
|
||||
**
|
||||
** Returns TRUE if two uuid match; FALSE otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_uuid_compare (tBT_UUID *p_src, tBT_UUID *p_tar, BOOLEAN is_precise)
|
||||
{
|
||||
UINT8 su[LEN_UUID_128], tu[LEN_UUID_128];
|
||||
UINT8 *ps, *pt;
|
||||
|
||||
/* any of the UUID is unspecified */
|
||||
if (p_src == 0 || p_tar == 0) {
|
||||
if (is_precise) {
|
||||
return FALSE;
|
||||
} else {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* If both are 16-bit, we can do a simple compare */
|
||||
if (p_src->len == 2 && p_tar->len == 2) {
|
||||
return p_src->uu.uuid16 == p_tar->uu.uuid16;
|
||||
}
|
||||
|
||||
/* One or both of the UUIDs is 128-bit */
|
||||
if (p_src->len == LEN_UUID_16) {
|
||||
/* convert a 16 bits UUID to 128 bits value */
|
||||
bta_gatt_convert_uuid16_to_uuid128(su, p_src->uu.uuid16);
|
||||
ps = su;
|
||||
} else {
|
||||
ps = p_src->uu.uuid128;
|
||||
}
|
||||
|
||||
if (p_tar->len == LEN_UUID_16) {
|
||||
/* convert a 16 bits UUID to 128 bits value */
|
||||
bta_gatt_convert_uuid16_to_uuid128(tu, p_tar->uu.uuid16);
|
||||
pt = tu;
|
||||
} else {
|
||||
pt = p_tar->uu.uuid128;
|
||||
}
|
||||
|
||||
return (memcmp(ps, pt, LEN_UUID_128) == 0);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_cl_get_regcb
|
||||
**
|
||||
** Description get registration control block by client interface.
|
||||
**
|
||||
** Returns pointer to the regcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_RCB *bta_gattc_cl_get_regcb(UINT8 client_if)
|
||||
{
|
||||
UINT8 i = 0;
|
||||
tBTA_GATTC_RCB *p_clrcb = &bta_gattc_cb.cl_rcb[0];
|
||||
|
||||
for (i = 0; i < BTA_GATTC_CL_MAX; i ++, p_clrcb ++) {
|
||||
if (p_clrcb->in_use &&
|
||||
p_clrcb->client_if == client_if) {
|
||||
return p_clrcb;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_num_reg_app
|
||||
**
|
||||
** Description find the number of registered application.
|
||||
**
|
||||
** Returns pointer to the regcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT8 bta_gattc_num_reg_app(void)
|
||||
{
|
||||
UINT8 i = 0, j = 0;
|
||||
|
||||
for (i = 0; i < BTA_GATTC_CL_MAX; i ++) {
|
||||
if (bta_gattc_cb.cl_rcb[i].in_use) {
|
||||
j ++;
|
||||
}
|
||||
}
|
||||
return j;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_find_clcb_by_cif
|
||||
**
|
||||
** Description get clcb by client interface and remote bd adddress
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_CLCB *bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda,
|
||||
tBTA_TRANSPORT transport)
|
||||
{
|
||||
tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++) {
|
||||
if (p_clcb->in_use &&
|
||||
p_clcb->p_rcb->client_if == client_if &&
|
||||
p_clcb->transport == transport &&
|
||||
bdcmp(p_clcb->bda, remote_bda) == 0) {
|
||||
return p_clcb;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_find_clcb_by_conn_id
|
||||
**
|
||||
** Description get clcb by connection ID
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_CLCB *bta_gattc_find_clcb_by_conn_id (UINT16 conn_id)
|
||||
{
|
||||
tBTA_GATTC_CLCB *p_clcb = &bta_gattc_cb.clcb[0];
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < BTA_GATTC_CLCB_MAX; i ++, p_clcb ++) {
|
||||
if (p_clcb->in_use &&
|
||||
p_clcb->bta_conn_id == conn_id) {
|
||||
return p_clcb;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_clcb_alloc
|
||||
**
|
||||
** Description allocate CLCB
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_CLCB *bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
|
||||
tBTA_TRANSPORT transport)
|
||||
{
|
||||
UINT8 i_clcb = 0;
|
||||
tBTA_GATTC_CLCB *p_clcb = NULL;
|
||||
|
||||
for (i_clcb = 0; i_clcb < BTA_GATTC_CLCB_MAX; i_clcb++) {
|
||||
if (!bta_gattc_cb.clcb[i_clcb].in_use) {
|
||||
#if BTA_GATT_DEBUG == TRUE
|
||||
APPL_TRACE_DEBUG("bta_gattc_clcb_alloc: found clcb[%d] available", i_clcb);
|
||||
#endif
|
||||
p_clcb = &bta_gattc_cb.clcb[i_clcb];
|
||||
p_clcb->in_use = TRUE;
|
||||
p_clcb->status = BTA_GATT_OK;
|
||||
p_clcb->transport = transport;
|
||||
bdcpy(p_clcb->bda, remote_bda);
|
||||
|
||||
p_clcb->p_rcb = bta_gattc_cl_get_regcb(client_if);
|
||||
|
||||
if ((p_clcb->p_srcb = bta_gattc_find_srcb(remote_bda)) == NULL) {
|
||||
p_clcb->p_srcb = bta_gattc_srcb_alloc(remote_bda);
|
||||
}
|
||||
|
||||
if (p_clcb->p_rcb != NULL && p_clcb->p_srcb != NULL) {
|
||||
p_clcb->p_srcb->num_clcb ++;
|
||||
p_clcb->p_rcb->num_clcb ++;
|
||||
} else {
|
||||
/* release this clcb if clcb or srcb allocation failed */
|
||||
p_clcb->in_use = FALSE;
|
||||
p_clcb = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return p_clcb;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_find_alloc_clcb
|
||||
**
|
||||
** Description find or allocate CLCB if not found.
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_CLCB *bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda,
|
||||
tBTA_TRANSPORT transport)
|
||||
{
|
||||
tBTA_GATTC_CLCB *p_clcb ;
|
||||
|
||||
if ((p_clcb = bta_gattc_find_clcb_by_cif(client_if, remote_bda, transport)) == NULL) {
|
||||
p_clcb = bta_gattc_clcb_alloc(client_if, remote_bda, transport);
|
||||
}
|
||||
return p_clcb;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_clcb_dealloc
|
||||
**
|
||||
** Description Deallocte a clcb
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb)
|
||||
{
|
||||
tBTA_GATTC_SERV *p_srcb = NULL;
|
||||
|
||||
if (p_clcb) {
|
||||
p_srcb = p_clcb->p_srcb;
|
||||
if (p_srcb->num_clcb) {
|
||||
p_srcb->num_clcb --;
|
||||
}
|
||||
|
||||
if (p_clcb->p_rcb->num_clcb) {
|
||||
p_clcb->p_rcb->num_clcb --;
|
||||
}
|
||||
|
||||
/* if the srcb is no longer needed, reset the state */
|
||||
if ( p_srcb->num_clcb == 0) {
|
||||
p_srcb->connected = FALSE;
|
||||
p_srcb->state = BTA_GATTC_SERV_IDLE;
|
||||
p_srcb->mtu = 0;
|
||||
}
|
||||
|
||||
utl_freebuf((void **)&p_clcb->p_q_cmd);
|
||||
|
||||
memset(p_clcb, 0, sizeof(tBTA_GATTC_CLCB));
|
||||
} else {
|
||||
APPL_TRACE_ERROR("bta_gattc_clcb_dealloc p_clcb=NULL");
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_find_srcb
|
||||
**
|
||||
** Description find server cache by remote bd address currently in use
|
||||
**
|
||||
** Returns pointer to the server cache.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_SERV *bta_gattc_find_srcb(BD_ADDR bda)
|
||||
{
|
||||
tBTA_GATTC_SERV *p_srcb = &bta_gattc_cb.known_server[0];
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_srcb ++) {
|
||||
if (p_srcb->in_use && bdcmp(p_srcb->server_bda, bda) == 0) {
|
||||
return p_srcb;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_find_srvr_cache
|
||||
**
|
||||
** Description find server cache by remote bd address
|
||||
**
|
||||
** Returns pointer to the server cache.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_SERV *bta_gattc_find_srvr_cache(BD_ADDR bda)
|
||||
{
|
||||
tBTA_GATTC_SERV *p_srcb = &bta_gattc_cb.known_server[0];
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_srcb ++) {
|
||||
if (bdcmp(p_srcb->server_bda, bda) == 0) {
|
||||
return p_srcb;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_find_scb_by_cid
|
||||
**
|
||||
** Description find server control block by connection ID
|
||||
**
|
||||
** Returns pointer to the server cache.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_SERV *bta_gattc_find_scb_by_cid (UINT16 conn_id)
|
||||
{
|
||||
tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
|
||||
|
||||
if (p_clcb) {
|
||||
return p_clcb->p_srcb;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_srcb_alloc
|
||||
**
|
||||
** Description allocate server cache control block
|
||||
**
|
||||
** Returns pointer to the server cache.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_SERV *bta_gattc_srcb_alloc(BD_ADDR bda)
|
||||
{
|
||||
tBTA_GATTC_SERV *p_tcb = &bta_gattc_cb.known_server[0],
|
||||
*p_recycle = NULL;
|
||||
BOOLEAN found = FALSE;
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_tcb ++) {
|
||||
if (!p_tcb->in_use) {
|
||||
found = TRUE;
|
||||
break;
|
||||
} else if (!p_tcb->connected) {
|
||||
p_recycle = p_tcb;
|
||||
}
|
||||
}
|
||||
|
||||
/* if not found, try to recycle one known device */
|
||||
if (!found && !p_recycle) {
|
||||
p_tcb = NULL;
|
||||
} else if (!found && p_recycle) {
|
||||
p_tcb = p_recycle;
|
||||
}
|
||||
|
||||
if (p_tcb != NULL) {
|
||||
while (!GKI_queue_is_empty(&p_tcb->cache_buffer)) {
|
||||
GKI_freebuf (GKI_dequeue (&p_tcb->cache_buffer));
|
||||
}
|
||||
|
||||
utl_freebuf((void **)&p_tcb->p_srvc_list);
|
||||
memset(p_tcb, 0 , sizeof(tBTA_GATTC_SERV));
|
||||
|
||||
p_tcb->in_use = TRUE;
|
||||
bdcpy(p_tcb->server_bda, bda);
|
||||
}
|
||||
return p_tcb;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_enqueue
|
||||
**
|
||||
** Description enqueue a client request in clcb.
|
||||
**
|
||||
** Returns success or failure.
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data)
|
||||
{
|
||||
|
||||
if (p_clcb->p_q_cmd == NULL) {
|
||||
p_clcb->p_q_cmd = p_data;
|
||||
} else {
|
||||
APPL_TRACE_ERROR("already has a pending command!!");
|
||||
/* skip the callback now. ----- need to send callback ? */
|
||||
}
|
||||
return (p_clcb->p_q_cmd != NULL) ? TRUE : FALSE;
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_pack_attr_uuid
|
||||
**
|
||||
** Description pack UUID into a stream.
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gattc_pack_attr_uuid(tBTA_GATTC_CACHE_ATTR *p_attr, tBT_UUID *p_uuid)
|
||||
{
|
||||
UINT8 *pp = (UINT8 *)p_attr->p_uuid;
|
||||
|
||||
memset(p_uuid, 0, sizeof(tBT_UUID));
|
||||
|
||||
p_uuid->len = p_attr->uuid_len;
|
||||
|
||||
if (p_attr->uuid_len == LEN_UUID_16) {
|
||||
STREAM_TO_UINT16(p_uuid->uu.uuid16, pp);
|
||||
} else {
|
||||
memcpy(p_uuid->uu.uuid128, pp, LEN_UUID_128);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_cpygattid
|
||||
**
|
||||
** Description copy two tBTA_GATT_ID value
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gattc_cpygattid(tBTA_GATT_ID *p_des, tBTA_GATT_ID *p_src)
|
||||
{
|
||||
memset ((void *)p_des, 0, sizeof(tBTA_GATT_ID));
|
||||
|
||||
p_des->inst_id = p_src->inst_id;
|
||||
|
||||
p_des->uuid.len = p_src->uuid.len;
|
||||
|
||||
if (p_des->uuid.len == LEN_UUID_16) {
|
||||
p_des->uuid.uu.uuid16 = p_src->uuid.uu.uuid16;
|
||||
} else if (p_des->uuid.len == LEN_UUID_128) {
|
||||
memcpy(p_des->uuid.uu.uuid128, p_src->uuid.uu.uuid128, LEN_UUID_128);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_gattid_compare
|
||||
**
|
||||
** Description compare two tBTA_GATT_ID type of pointer
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_gattid_compare(tBTA_GATT_ID *p_src, tBTA_GATT_ID *p_tar)
|
||||
{
|
||||
if (p_src->inst_id == p_tar->inst_id &&
|
||||
bta_gattc_uuid_compare (&p_src->uuid, &p_tar->uuid, TRUE )) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_srvcid_compare
|
||||
**
|
||||
** Description compare two tBTA_GATT_SRVC_ID type of pointer
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_srvcid_compare(tBTA_GATT_SRVC_ID *p_src, tBTA_GATT_SRVC_ID *p_tar)
|
||||
{
|
||||
if (p_src->is_primary == p_tar->is_primary &&
|
||||
bta_gattc_gattid_compare (&p_src->id, &p_tar->id)) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_charid_compare
|
||||
**
|
||||
** Description compare two tBTA_GATTC_CHAR_ID type of pointer
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_charid_compare(tBTA_GATTC_CHAR_ID *p_src, tBTA_GATTC_CHAR_ID *p_tar)
|
||||
{
|
||||
if (bta_gattc_gattid_compare (&p_src->char_id, &p_tar->char_id) &&
|
||||
bta_gattc_srvcid_compare (&p_src->srvc_id, &p_tar->srvc_id)) {
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_check_notif_registry
|
||||
**
|
||||
** Description check if the service notificaition has been registered.
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_check_notif_registry(tBTA_GATTC_RCB *p_clreg, tBTA_GATTC_SERV *p_srcb,
|
||||
tBTA_GATTC_NOTIFY *p_notify)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++) {
|
||||
if (p_clreg->notif_reg[i].in_use &&
|
||||
bdcmp(p_clreg->notif_reg[i].remote_bda, p_srcb->server_bda) == 0 &&
|
||||
bta_gattc_charid_compare (&p_clreg->notif_reg[i].char_id, &p_notify->char_id)) {
|
||||
APPL_TRACE_DEBUG("Notification registered!");
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_clear_notif_registration
|
||||
**
|
||||
** Description clear up the notification registration information by BD_ADDR.
|
||||
**
|
||||
** Returns None.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gattc_clear_notif_registration(UINT16 conn_id)
|
||||
{
|
||||
BD_ADDR remote_bda;
|
||||
tBTA_GATTC_IF gatt_if;
|
||||
tBTA_GATTC_RCB *p_clrcb ;
|
||||
UINT8 i;
|
||||
tGATT_TRANSPORT transport;
|
||||
|
||||
if (GATT_GetConnectionInfor(conn_id, &gatt_if, remote_bda, &transport)) {
|
||||
if ((p_clrcb = bta_gattc_cl_get_regcb(gatt_if)) != NULL) {
|
||||
for (i = 0 ; i < BTA_GATTC_NOTIF_REG_MAX; i ++) {
|
||||
if (p_clrcb->notif_reg[i].in_use &&
|
||||
!bdcmp(p_clrcb->notif_reg[i].remote_bda, remote_bda)) {
|
||||
memset(&p_clrcb->notif_reg[i], 0, sizeof(tBTA_GATTC_NOTIF_REG));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_ERROR("can not clear indication/notif registration for unknown app");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_pack_cb_data
|
||||
**
|
||||
** Description pack the data from read response into callback data structure.
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATT_STATUS bta_gattc_pack_read_cb_data(tBTA_GATTC_SERV *p_srcb,
|
||||
tBT_UUID *p_descr_uuid,
|
||||
tGATT_VALUE *p_attr,
|
||||
tBTA_GATT_READ_VAL *p_value)
|
||||
{
|
||||
UINT8 i = 0, *pp = p_attr->value;
|
||||
tBT_UUID uuid = {LEN_UUID_16, {GATT_UUID_CHAR_AGG_FORMAT}};
|
||||
UINT16 handle;
|
||||
tBTA_GATT_STATUS status = BTA_GATT_OK;
|
||||
|
||||
/* GATT_UUID_CHAR_AGG_FORMAT */
|
||||
if (bta_gattc_uuid_compare (&uuid, p_descr_uuid, TRUE)) {
|
||||
while (p_attr->len >= 2 && i < BTA_GATTC_MULTI_MAX) {
|
||||
STREAM_TO_UINT16(handle, pp);
|
||||
|
||||
if (bta_gattc_handle2id(p_srcb,
|
||||
handle,
|
||||
&p_value->aggre_value.pre_format[i].char_id.srvc_id,
|
||||
&p_value->aggre_value.pre_format[i].char_id.char_id,
|
||||
&p_value->aggre_value.pre_format[i].descr_id) == FALSE) {
|
||||
status = BTA_GATT_INTERNAL_ERROR;
|
||||
APPL_TRACE_ERROR("can not map to GATT ID. handle = 0x%04x", handle);
|
||||
break;
|
||||
}
|
||||
i ++;
|
||||
p_attr->len -= 2;
|
||||
}
|
||||
p_value->aggre_value.num_pres_fmt = i;
|
||||
} else {
|
||||
/* all others, take as raw format */
|
||||
p_value->unformat.len = p_attr->len;
|
||||
p_value->unformat.p_value = p_attr->value;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_mark_bg_conn
|
||||
**
|
||||
** Description mark background connection status when a bg connection is initiated
|
||||
** or terminated.
|
||||
**
|
||||
** Returns TRUE if success; FALSE otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_mark_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR_PTR remote_bda_ptr,
|
||||
BOOLEAN add, BOOLEAN is_listen)
|
||||
{
|
||||
tBTA_GATTC_BG_TCK *p_bg_tck = &bta_gattc_cb.bg_track[0];
|
||||
UINT8 i = 0;
|
||||
tBTA_GATTC_CIF_MASK *p_cif_mask;
|
||||
|
||||
for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_bg_tck ++) {
|
||||
if (p_bg_tck->in_use &&
|
||||
((remote_bda_ptr != NULL && bdcmp(p_bg_tck->remote_bda, remote_bda_ptr) == 0) ||
|
||||
(remote_bda_ptr == NULL && bdcmp(p_bg_tck->remote_bda, dummy_bda) == 0))) {
|
||||
p_cif_mask = is_listen ? &p_bg_tck->cif_adv_mask : &p_bg_tck->cif_mask;
|
||||
|
||||
if (add)
|
||||
/* mask on the cif bit */
|
||||
{
|
||||
*p_cif_mask |= (1 << (client_if - 1));
|
||||
} else {
|
||||
if (client_if != 0) {
|
||||
*p_cif_mask &= (~(1 << (client_if - 1)));
|
||||
} else {
|
||||
*p_cif_mask = 0;
|
||||
}
|
||||
}
|
||||
/* no BG connection for this device, make it available */
|
||||
if (p_bg_tck->cif_mask == 0 && p_bg_tck->cif_adv_mask == 0) {
|
||||
memset(p_bg_tck, 0, sizeof(tBTA_GATTC_BG_TCK));
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
if (!add) {
|
||||
if (remote_bda_ptr) {
|
||||
// bdstr_t bdstr = {0};
|
||||
char bdstr[18] = {0};
|
||||
APPL_TRACE_ERROR("%s unable to find the bg connection mask for: %s", __func__,
|
||||
bdaddr_to_string((bt_bdaddr_t *)remote_bda_ptr, bdstr, sizeof(bdstr)));
|
||||
}
|
||||
return FALSE;
|
||||
} else { /* adding a new device mask */
|
||||
for (i = 0, p_bg_tck = &bta_gattc_cb.bg_track[0];
|
||||
i < BTA_GATTC_KNOWN_SR_MAX; i ++, p_bg_tck ++) {
|
||||
if (!p_bg_tck->in_use) {
|
||||
p_bg_tck->in_use = TRUE;
|
||||
if (remote_bda_ptr) {
|
||||
bdcpy(p_bg_tck->remote_bda, remote_bda_ptr);
|
||||
} else {
|
||||
bdcpy(p_bg_tck->remote_bda, dummy_bda);
|
||||
}
|
||||
|
||||
p_cif_mask = is_listen ? &p_bg_tck->cif_adv_mask : &p_bg_tck->cif_mask;
|
||||
|
||||
*p_cif_mask = (1 << (client_if - 1));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
APPL_TRACE_ERROR("no available space to mark the bg connection status");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_check_bg_conn
|
||||
**
|
||||
** Description check if this is a background connection background connection.
|
||||
**
|
||||
** Returns TRUE if success; FALSE otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_check_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR remote_bda, UINT8 role)
|
||||
{
|
||||
tBTA_GATTC_BG_TCK *p_bg_tck = &bta_gattc_cb.bg_track[0];
|
||||
UINT8 i = 0;
|
||||
BOOLEAN is_bg_conn = FALSE;
|
||||
|
||||
for (i = 0; i < BTA_GATTC_KNOWN_SR_MAX && !is_bg_conn; i ++, p_bg_tck ++) {
|
||||
if (p_bg_tck->in_use &&
|
||||
(bdcmp(p_bg_tck->remote_bda, remote_bda) == 0 ||
|
||||
bdcmp(p_bg_tck->remote_bda, dummy_bda) == 0)) {
|
||||
if (((p_bg_tck->cif_mask & (1 << (client_if - 1))) != 0) &&
|
||||
role == HCI_ROLE_MASTER) {
|
||||
is_bg_conn = TRUE;
|
||||
}
|
||||
|
||||
if (((p_bg_tck->cif_adv_mask & (1 << (client_if - 1))) != 0) &&
|
||||
role == HCI_ROLE_SLAVE) {
|
||||
is_bg_conn = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return is_bg_conn;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_send_open_cback
|
||||
**
|
||||
** Description send open callback
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status,
|
||||
BD_ADDR remote_bda, UINT16 conn_id,
|
||||
tBTA_TRANSPORT transport, UINT16 mtu)
|
||||
{
|
||||
tBTA_GATTC cb_data;
|
||||
|
||||
if (p_clreg->p_cback) {
|
||||
memset(&cb_data, 0, sizeof(tBTA_GATTC));
|
||||
|
||||
cb_data.open.status = status;
|
||||
cb_data.open.client_if = p_clreg->client_if;
|
||||
cb_data.open.conn_id = conn_id;
|
||||
cb_data.open.mtu = mtu;
|
||||
cb_data.open.transport = transport;
|
||||
bdcpy(cb_data.open.remote_bda, remote_bda);
|
||||
|
||||
(*p_clreg->p_cback)(BTA_GATTC_OPEN_EVT, &cb_data);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_conn_alloc
|
||||
**
|
||||
** Description allocate connection tracking spot
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_CONN *bta_gattc_conn_alloc(BD_ADDR remote_bda)
|
||||
{
|
||||
UINT8 i_conn = 0;
|
||||
tBTA_GATTC_CONN *p_conn = &bta_gattc_cb.conn_track[0];
|
||||
|
||||
for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++) {
|
||||
if (!p_conn->in_use) {
|
||||
#if BTA_GATT_DEBUG == TRUE
|
||||
APPL_TRACE_DEBUG("bta_gattc_conn_alloc: found conn_track[%d] available", i_conn);
|
||||
#endif
|
||||
p_conn->in_use = TRUE;
|
||||
bdcpy(p_conn->remote_bda, remote_bda);
|
||||
return p_conn;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_conn_find
|
||||
**
|
||||
** Description allocate connection tracking spot
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_CONN *bta_gattc_conn_find(BD_ADDR remote_bda)
|
||||
{
|
||||
UINT8 i_conn = 0;
|
||||
tBTA_GATTC_CONN *p_conn = &bta_gattc_cb.conn_track[0];
|
||||
|
||||
for (i_conn = 0; i_conn < BTA_GATTC_CONN_MAX; i_conn++, p_conn ++) {
|
||||
if (p_conn->in_use && bdcmp(remote_bda, p_conn->remote_bda) == 0) {
|
||||
#if BTA_GATT_DEBUG == TRUE
|
||||
APPL_TRACE_DEBUG("bta_gattc_conn_find: found conn_track[%d] matched", i_conn);
|
||||
#endif
|
||||
return p_conn;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_conn_find_alloc
|
||||
**
|
||||
** Description find or allocate connection tracking spot
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_CONN *bta_gattc_conn_find_alloc(BD_ADDR remote_bda)
|
||||
{
|
||||
tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find (remote_bda);
|
||||
|
||||
if (p_conn == NULL) {
|
||||
p_conn = bta_gattc_conn_alloc(remote_bda);
|
||||
}
|
||||
return p_conn;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_conn_dealloc
|
||||
**
|
||||
** Description de-allocate connection tracking spot
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gattc_conn_dealloc(BD_ADDR remote_bda)
|
||||
{
|
||||
tBTA_GATTC_CONN *p_conn = bta_gattc_conn_find (remote_bda);
|
||||
|
||||
if (p_conn != NULL) {
|
||||
p_conn->in_use = FALSE;
|
||||
memset(p_conn->remote_bda, 0, BD_ADDR_LEN);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_find_int_conn_clcb
|
||||
**
|
||||
** Description try to locate a clcb when an internal connecion event arrives.
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_CLCB *bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTC_CLCB *p_clcb = NULL;
|
||||
|
||||
if (p_msg->int_conn.role == HCI_ROLE_SLAVE) {
|
||||
bta_gattc_conn_find_alloc(p_msg->int_conn.remote_bda);
|
||||
}
|
||||
|
||||
/* try to locate a logic channel */
|
||||
if ((p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
|
||||
p_msg->int_conn.remote_bda,
|
||||
p_msg->int_conn.transport)) == NULL) {
|
||||
/* for a background connection or listening connection */
|
||||
if (/*p_msg->int_conn.role == HCI_ROLE_SLAVE || */
|
||||
bta_gattc_check_bg_conn(p_msg->int_conn.client_if,
|
||||
p_msg->int_conn.remote_bda,
|
||||
p_msg->int_conn.role)) {
|
||||
/* allocate a new channel */
|
||||
p_clcb = bta_gattc_clcb_alloc(p_msg->int_conn.client_if,
|
||||
p_msg->int_conn.remote_bda,
|
||||
p_msg->int_conn.transport);
|
||||
}
|
||||
}
|
||||
return p_clcb;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_find_int_disconn_clcb
|
||||
**
|
||||
** Description try to locate a clcb when an internal disconnect callback arrives.
|
||||
**
|
||||
** Returns pointer to the clcb
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTC_CLCB *bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTC_CLCB *p_clcb = NULL;
|
||||
|
||||
bta_gattc_conn_dealloc(p_msg->int_conn.remote_bda);
|
||||
if ((p_clcb = bta_gattc_find_clcb_by_conn_id(p_msg->int_conn.hdr.layer_specific)) == NULL) {
|
||||
/* connection attempt failed, send connection callback event */
|
||||
p_clcb = bta_gattc_find_clcb_by_cif(p_msg->int_conn.client_if,
|
||||
p_msg->int_conn.remote_bda,
|
||||
p_msg->int_conn.transport);
|
||||
}
|
||||
if (p_clcb == NULL) {
|
||||
APPL_TRACE_DEBUG(" disconnection ID: [%d] not used by BTA",
|
||||
p_msg->int_conn.hdr.layer_specific);
|
||||
}
|
||||
return p_clcb;
|
||||
}
|
||||
|
||||
#endif /* BTA_GATT_INCLUDED */
|
||||
905
components/bt/bluedroid/bta/gatt/bta_gatts_act.c
Normal file
905
components/bt/bluedroid/bta/gatt/bta_gatts_act.c
Normal file
@@ -0,0 +1,905 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the GATT Server action functions for the state
|
||||
* machine.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
#include "bt_target.h"
|
||||
|
||||
#if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
|
||||
|
||||
#include "utl.h"
|
||||
#include "gki.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_gatts_int.h"
|
||||
#include "bta_gatts_co.h"
|
||||
#include "btm_ble_api.h"
|
||||
// #include "btif/include/btif_debug_conn.h"
|
||||
#include <string.h>
|
||||
|
||||
static void bta_gatts_nv_save_cback(BOOLEAN is_saved, tGATTS_HNDL_RANGE *p_hndl_range);
|
||||
static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd, tGATTS_SRV_CHG_REQ *p_req,
|
||||
tGATTS_SRV_CHG_RSP *p_rsp);
|
||||
|
||||
static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
|
||||
BOOLEAN connected, tGATT_DISCONN_REASON reason,
|
||||
tGATT_TRANSPORT transport);
|
||||
static void bta_gatts_send_request_cback (UINT16 conn_id,
|
||||
UINT32 trans_id,
|
||||
tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data);
|
||||
static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested);
|
||||
|
||||
static tGATT_CBACK bta_gatts_cback = {
|
||||
bta_gatts_conn_cback,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
bta_gatts_send_request_cback,
|
||||
NULL,
|
||||
bta_gatts_cong_cback
|
||||
};
|
||||
|
||||
tGATT_APPL_INFO bta_gatts_nv_cback = {
|
||||
bta_gatts_nv_save_cback,
|
||||
bta_gatts_nv_srv_chg_cback
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_nv_save_cback
|
||||
**
|
||||
** Description NV save callback function.
|
||||
**
|
||||
** Parameter is_add: true is to add a handle range; otherwise is to delete.
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_gatts_nv_save_cback(BOOLEAN is_add, tGATTS_HNDL_RANGE *p_hndl_range)
|
||||
{
|
||||
bta_gatts_co_update_handle_range(is_add, (tBTA_GATTS_HNDL_RANGE *)p_hndl_range);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_nv_srv_chg_cback
|
||||
**
|
||||
** Description NV save callback function.
|
||||
**
|
||||
** Parameter is_add: true is to add a handle range; otherwise is to delete.
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
static BOOLEAN bta_gatts_nv_srv_chg_cback(tGATTS_SRV_CHG_CMD cmd,
|
||||
tGATTS_SRV_CHG_REQ *p_req, tGATTS_SRV_CHG_RSP *p_rsp)
|
||||
{
|
||||
return bta_gatts_co_srv_chg((tBTA_GATTS_SRV_CHG_CMD) cmd,
|
||||
(tBTA_GATTS_SRV_CHG_REQ *) p_req,
|
||||
(tBTA_GATTS_SRV_CHG_RSP *) p_rsp);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_enable
|
||||
**
|
||||
** Description enable BTA GATTS module.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_enable(tBTA_GATTS_CB *p_cb)
|
||||
{
|
||||
UINT8 index = 0;
|
||||
tBTA_GATTS_HNDL_RANGE handle_range;
|
||||
|
||||
if (p_cb->enabled) {
|
||||
APPL_TRACE_DEBUG("GATTS already enabled.");
|
||||
} else {
|
||||
memset(p_cb, 0, sizeof(tBTA_GATTS_CB));
|
||||
|
||||
p_cb->enabled = TRUE;
|
||||
|
||||
while ( bta_gatts_co_load_handle_range(index, &handle_range)) {
|
||||
GATTS_AddHandleRange((tGATTS_HNDL_RANGE *)&handle_range);
|
||||
memset(&handle_range, 0, sizeof(tGATTS_HNDL_RANGE));
|
||||
index++;
|
||||
}
|
||||
|
||||
APPL_TRACE_DEBUG("bta_gatts_enable: num of handle range added=%d", index);
|
||||
|
||||
if (!GATTS_NVRegister(&bta_gatts_nv_cback)) {
|
||||
APPL_TRACE_ERROR("BTA GATTS NV register failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_api_disable
|
||||
**
|
||||
** Description disable BTA GATTS module.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_api_disable(tBTA_GATTS_CB *p_cb)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
if (p_cb->enabled) {
|
||||
for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++) {
|
||||
if (p_cb->rcb[i].in_use) {
|
||||
GATT_Deregister(p_cb->rcb[i].gatt_if);
|
||||
}
|
||||
}
|
||||
memset(p_cb, 0, sizeof(tBTA_GATTS_CB));
|
||||
} else {
|
||||
APPL_TRACE_ERROR("GATTS not enabled");
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_register
|
||||
**
|
||||
** Description register an application.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_register(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_INT_START_IF *p_buf;
|
||||
tBTA_GATTS cb_data;
|
||||
tBTA_GATT_STATUS status = BTA_GATT_OK;
|
||||
UINT8 i, first_unuse = 0xff;
|
||||
|
||||
if (p_cb->enabled == FALSE) {
|
||||
bta_gatts_enable(p_cb);
|
||||
}
|
||||
|
||||
for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++) {
|
||||
if (p_cb->rcb[i].in_use) {
|
||||
if (bta_gatts_uuid_compare(p_cb->rcb[i].app_uuid, p_msg->api_reg.app_uuid)) {
|
||||
APPL_TRACE_ERROR("application already registered.\n");
|
||||
status = BTA_GATT_DUP_REG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (status == BTA_GATT_OK) {
|
||||
for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++) {
|
||||
if (first_unuse == 0xff && !p_cb->rcb[i].in_use) {
|
||||
first_unuse = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cb_data.reg_oper.server_if = BTA_GATTS_INVALID_IF;
|
||||
// btla-specific ++
|
||||
memcpy(&cb_data.reg_oper.uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
|
||||
// btla-specific --
|
||||
if (first_unuse != 0xff) {
|
||||
APPL_TRACE_VERBOSE("register application first_unuse rcb_idx = %d", first_unuse);
|
||||
|
||||
p_cb->rcb[first_unuse].in_use = TRUE;
|
||||
p_cb->rcb[first_unuse].p_cback = p_msg->api_reg.p_cback;
|
||||
memcpy(&p_cb->rcb[first_unuse].app_uuid, &p_msg->api_reg.app_uuid, sizeof(tBT_UUID));
|
||||
cb_data.reg_oper.server_if =
|
||||
p_cb->rcb[first_unuse].gatt_if =
|
||||
GATT_Register(&p_msg->api_reg.app_uuid, &bta_gatts_cback);
|
||||
if ( !p_cb->rcb[first_unuse].gatt_if) {
|
||||
status = BTA_GATT_NO_RESOURCES;
|
||||
} else {
|
||||
if ((p_buf =
|
||||
(tBTA_GATTS_INT_START_IF *) GKI_getbuf(sizeof(tBTA_GATTS_INT_START_IF))) != NULL) {
|
||||
p_buf->hdr.event = BTA_GATTS_INT_START_IF_EVT;
|
||||
p_buf->server_if = p_cb->rcb[first_unuse].gatt_if;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
} else {
|
||||
status = BTA_GATT_NO_RESOURCES;
|
||||
memset( &p_cb->rcb[first_unuse], 0 , sizeof(tBTA_GATTS_RCB));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
status = BTA_GATT_NO_RESOURCES;
|
||||
}
|
||||
|
||||
}
|
||||
cb_data.reg_oper.status = status;
|
||||
if (p_msg->api_reg.p_cback) {
|
||||
(*p_msg->api_reg.p_cback)(BTA_GATTS_REG_EVT, &cb_data);
|
||||
}
|
||||
|
||||
LOG_ERROR("status=%x\n", status);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_start_if
|
||||
**
|
||||
** Description start an application interface.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_start_if(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
UNUSED(p_cb);
|
||||
|
||||
if (bta_gatts_find_app_rcb_by_app_if(p_msg->int_start_if.server_if)) {
|
||||
GATT_StartIf(p_msg->int_start_if.server_if);
|
||||
} else {
|
||||
APPL_TRACE_ERROR("Unable to start app.: Unknown interface =%d",
|
||||
p_msg->int_start_if.server_if );
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_deregister
|
||||
**
|
||||
** Description deregister an application.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_deregister(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATT_STATUS status = BTA_GATT_ERROR;
|
||||
tBTA_GATTS_CBACK *p_cback = NULL;
|
||||
UINT8 i;
|
||||
tBTA_GATTS cb_data;
|
||||
|
||||
cb_data.reg_oper.server_if = p_msg->api_dereg.server_if;
|
||||
cb_data.reg_oper.status = status;
|
||||
|
||||
for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++) {
|
||||
if (p_cb->rcb[i].in_use && p_cb->rcb[i].gatt_if == p_msg->api_dereg.server_if) {
|
||||
p_cback = p_cb->rcb[i].p_cback;
|
||||
status = BTA_GATT_OK;
|
||||
|
||||
/* deregister the app */
|
||||
GATT_Deregister(p_cb->rcb[i].gatt_if);
|
||||
|
||||
/* reset cb */
|
||||
memset(&p_cb->rcb[i], 0, sizeof(tBTA_GATTS_RCB));
|
||||
cb_data.reg_oper.status = status;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_cback) {
|
||||
(*p_cback)(BTA_GATTS_DEREG_EVT, &cb_data);
|
||||
} else {
|
||||
APPL_TRACE_ERROR("application not registered.");
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_create_srvc
|
||||
**
|
||||
** Description action function to create a service.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_create_srvc(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
UINT8 rcb_idx;
|
||||
tBTA_GATTS cb_data;
|
||||
UINT8 srvc_idx;
|
||||
UINT16 service_id = 0;
|
||||
|
||||
cb_data.create.status = BTA_GATT_ERROR;
|
||||
|
||||
rcb_idx = bta_gatts_find_app_rcb_idx_by_app_if(p_cb, p_msg->api_create_svc.server_if);
|
||||
|
||||
APPL_TRACE_DEBUG("create service rcb_idx = %d", rcb_idx);
|
||||
|
||||
if (rcb_idx != BTA_GATTS_INVALID_APP) {
|
||||
if ((srvc_idx = bta_gatts_alloc_srvc_cb(p_cb, rcb_idx)) != BTA_GATTS_INVALID_APP) {
|
||||
/* create the service now */
|
||||
service_id = GATTS_CreateService (p_cb->rcb[rcb_idx].gatt_if,
|
||||
&p_msg->api_create_svc.service_uuid,
|
||||
p_msg->api_create_svc.inst,
|
||||
p_msg->api_create_svc.num_handle,
|
||||
p_msg->api_create_svc.is_pri);
|
||||
|
||||
if (service_id != 0) {
|
||||
memcpy(&p_cb->srvc_cb[srvc_idx].service_uuid,
|
||||
&p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
|
||||
p_cb->srvc_cb[srvc_idx].service_id = service_id;
|
||||
p_cb->srvc_cb[srvc_idx].inst_num = p_msg->api_create_svc.inst;
|
||||
p_cb->srvc_cb[srvc_idx].idx = srvc_idx;
|
||||
|
||||
cb_data.create.status = BTA_GATT_OK;
|
||||
cb_data.create.service_id = service_id;
|
||||
// btla-specific ++
|
||||
cb_data.create.is_primary = p_msg->api_create_svc.is_pri;
|
||||
// btla-specific --
|
||||
cb_data.create.server_if = p_cb->rcb[rcb_idx].gatt_if;
|
||||
} else {
|
||||
cb_data.status = BTA_GATT_ERROR;
|
||||
memset(&p_cb->srvc_cb[srvc_idx], 0, sizeof(tBTA_GATTS_SRVC_CB));
|
||||
APPL_TRACE_ERROR("service creation failed.");
|
||||
}
|
||||
// btla-specific ++
|
||||
memcpy(&cb_data.create.uuid, &p_msg->api_create_svc.service_uuid, sizeof(tBT_UUID));
|
||||
cb_data.create.svc_instance = p_msg->api_create_svc.inst;
|
||||
// btla-specific --
|
||||
}
|
||||
if (p_cb->rcb[rcb_idx].p_cback) {
|
||||
(* p_cb->rcb[rcb_idx].p_cback)(BTA_GATTS_CREATE_EVT, &cb_data);
|
||||
}
|
||||
} else { /* application not registered */
|
||||
APPL_TRACE_ERROR("Application not registered");
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_add_include_srvc
|
||||
**
|
||||
** Description action function to add an included service.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_add_include_srvc(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
|
||||
UINT16 attr_id = 0;
|
||||
tBTA_GATTS cb_data;
|
||||
|
||||
attr_id = GATTS_AddIncludeService(p_msg->api_add_incl_srvc.hdr.layer_specific,
|
||||
p_msg->api_add_incl_srvc.included_service_id);
|
||||
|
||||
cb_data.add_result.server_if = p_rcb->gatt_if;
|
||||
cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
|
||||
cb_data.add_result.attr_id = attr_id;
|
||||
|
||||
if (attr_id) {
|
||||
cb_data.add_result.status = BTA_GATT_OK;
|
||||
} else {
|
||||
cb_data.add_result.status = BTA_GATT_ERROR;
|
||||
}
|
||||
|
||||
if (p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_ADD_INCL_SRVC_EVT, &cb_data);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_add_char
|
||||
**
|
||||
** Description action function to add characteristic.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
|
||||
UINT16 attr_id = 0;
|
||||
tBTA_GATTS cb_data;
|
||||
|
||||
attr_id = GATTS_AddCharacteristic(p_msg->api_add_char.hdr.layer_specific,
|
||||
&p_msg->api_add_char.char_uuid,
|
||||
p_msg->api_add_char.perm,
|
||||
p_msg->api_add_char.property);
|
||||
cb_data.add_result.server_if = p_rcb->gatt_if;
|
||||
cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
|
||||
cb_data.add_result.attr_id = attr_id;
|
||||
// btla-specific ++
|
||||
memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char.char_uuid, sizeof(tBT_UUID));
|
||||
// btla-specific --
|
||||
|
||||
if (attr_id) {
|
||||
cb_data.add_result.status = BTA_GATT_OK;
|
||||
} else {
|
||||
cb_data.add_result.status = BTA_GATT_ERROR;
|
||||
}
|
||||
|
||||
if (p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_EVT, &cb_data);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_add_char_descr
|
||||
**
|
||||
** Description action function to add characteristic descriptor.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
|
||||
UINT16 attr_id = 0;
|
||||
tBTA_GATTS cb_data;
|
||||
|
||||
attr_id = GATTS_AddCharDescriptor(p_msg->api_add_char_descr.hdr.layer_specific,
|
||||
p_msg->api_add_char_descr.perm,
|
||||
&p_msg->api_add_char_descr.descr_uuid);
|
||||
|
||||
cb_data.add_result.server_if = p_rcb->gatt_if;
|
||||
cb_data.add_result.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
|
||||
cb_data.add_result.attr_id = attr_id;
|
||||
// btla-specific ++
|
||||
memcpy(&cb_data.add_result.char_uuid, &p_msg->api_add_char_descr.descr_uuid, sizeof(tBT_UUID));
|
||||
// btla-specific --
|
||||
|
||||
if (attr_id) {
|
||||
cb_data.add_result.status = BTA_GATT_OK;
|
||||
} else {
|
||||
cb_data.add_result.status = BTA_GATT_ERROR;
|
||||
}
|
||||
|
||||
if (p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_ADD_CHAR_DESCR_EVT, &cb_data);
|
||||
}
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_delete_service
|
||||
**
|
||||
** Description action function to delete a service.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
|
||||
tBTA_GATTS cb_data;
|
||||
|
||||
cb_data.srvc_oper.server_if = p_rcb->gatt_if;
|
||||
cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
|
||||
|
||||
if (GATTS_DeleteService(p_rcb->gatt_if,
|
||||
&p_srvc_cb->service_uuid,
|
||||
p_srvc_cb->inst_num)) {
|
||||
cb_data.srvc_oper.status = BTA_GATT_OK;
|
||||
memset(p_srvc_cb, 0, sizeof(tBTA_GATTS_SRVC_CB));
|
||||
} else {
|
||||
cb_data.srvc_oper.status = BTA_GATT_ERROR;
|
||||
}
|
||||
|
||||
if (p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_DELELTE_EVT, &cb_data);
|
||||
}
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_start_service
|
||||
**
|
||||
** Description action function to start a service.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_start_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
|
||||
tBTA_GATTS cb_data;
|
||||
|
||||
cb_data.srvc_oper.server_if = p_rcb->gatt_if;
|
||||
cb_data.srvc_oper.service_id = p_msg->api_add_incl_srvc.hdr.layer_specific;
|
||||
|
||||
if (GATTS_StartService(p_rcb->gatt_if,
|
||||
p_srvc_cb->service_id,
|
||||
p_msg->api_start.transport) == GATT_SUCCESS) {
|
||||
APPL_TRACE_DEBUG("bta_gatts_start_service service_id= %d", p_srvc_cb->service_id);
|
||||
cb_data.srvc_oper.status = BTA_GATT_OK;
|
||||
} else {
|
||||
cb_data.srvc_oper.status = BTA_GATT_ERROR;
|
||||
}
|
||||
|
||||
if (p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_START_EVT, &cb_data);
|
||||
}
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_stop_service
|
||||
**
|
||||
** Description action function to stop a service.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb = &bta_gatts_cb.rcb[p_srvc_cb->rcb_idx];
|
||||
tBTA_GATTS cb_data;
|
||||
UNUSED(p_msg);
|
||||
|
||||
GATTS_StopService(p_srvc_cb->service_id);
|
||||
cb_data.srvc_oper.server_if = p_rcb->gatt_if;
|
||||
cb_data.srvc_oper.service_id = p_srvc_cb->service_id;
|
||||
cb_data.srvc_oper.status = BTA_GATT_OK;
|
||||
APPL_TRACE_ERROR("bta_gatts_stop_service service_id= %d", p_srvc_cb->service_id);
|
||||
|
||||
if (p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_STOP_EVT, &cb_data);
|
||||
}
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_send_rsp
|
||||
**
|
||||
** Description GATTS send response.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_send_rsp (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
UNUSED(p_cb);
|
||||
|
||||
if (GATTS_SendRsp (p_msg->api_rsp.hdr.layer_specific,
|
||||
p_msg->api_rsp.trans_id,
|
||||
p_msg->api_rsp.status,
|
||||
(tGATTS_RSP *)p_msg->api_rsp.p_rsp) != GATT_SUCCESS) {
|
||||
APPL_TRACE_ERROR("Sending response failed\n");
|
||||
}
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_indicate_handle
|
||||
**
|
||||
** Description GATTS send handle value indication or notification.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_SRVC_CB *p_srvc_cb;
|
||||
tBTA_GATTS_RCB *p_rcb = NULL;
|
||||
tBTA_GATT_STATUS status = BTA_GATT_ILLEGAL_PARAMETER;
|
||||
tGATT_IF gatt_if;
|
||||
BD_ADDR remote_bda;
|
||||
tBTA_TRANSPORT transport;
|
||||
tBTA_GATTS cb_data;
|
||||
|
||||
p_srvc_cb = bta_gatts_find_srvc_cb_by_attr_id (p_cb, p_msg->api_indicate.attr_id);
|
||||
|
||||
if (p_srvc_cb ) {
|
||||
if (GATT_GetConnectionInfor(p_msg->api_indicate.hdr.layer_specific,
|
||||
&gatt_if, remote_bda, &transport)) {
|
||||
p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
|
||||
|
||||
if (p_msg->api_indicate.need_confirm)
|
||||
|
||||
status = GATTS_HandleValueIndication (p_msg->api_indicate.hdr.layer_specific,
|
||||
p_msg->api_indicate.attr_id,
|
||||
p_msg->api_indicate.len,
|
||||
p_msg->api_indicate.value);
|
||||
else
|
||||
status = GATTS_HandleValueNotification (p_msg->api_indicate.hdr.layer_specific,
|
||||
p_msg->api_indicate.attr_id,
|
||||
p_msg->api_indicate.len,
|
||||
p_msg->api_indicate.value);
|
||||
|
||||
/* if over BR_EDR, inform PM for mode change */
|
||||
if (transport == BTA_TRANSPORT_BR_EDR) {
|
||||
bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
|
||||
bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, remote_bda);
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_ERROR("Unknown connection ID: %d fail sending notification",
|
||||
p_msg->api_indicate.hdr.layer_specific);
|
||||
}
|
||||
|
||||
if ((status != GATT_SUCCESS || !p_msg->api_indicate.need_confirm) &&
|
||||
p_rcb && p_cb->rcb[p_srvc_cb->rcb_idx].p_cback) {
|
||||
cb_data.req_data.status = status;
|
||||
cb_data.req_data.conn_id = p_msg->api_indicate.hdr.layer_specific;
|
||||
|
||||
(*p_rcb->p_cback)(BTA_GATTS_CONF_EVT, &cb_data);
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_ERROR("Not an registered servce attribute ID: 0x%04x",
|
||||
p_msg->api_indicate.attr_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_open
|
||||
**
|
||||
** Description
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb = NULL;
|
||||
tBTA_GATT_STATUS status = BTA_GATT_ERROR;
|
||||
UINT16 conn_id;
|
||||
UNUSED(p_cb);
|
||||
|
||||
if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_open.server_if)) != NULL) {
|
||||
/* should always get the connection ID */
|
||||
if (GATT_Connect(p_rcb->gatt_if, p_msg->api_open.remote_bda,
|
||||
p_msg->api_open.is_direct, p_msg->api_open.transport)) {
|
||||
status = BTA_GATT_OK;
|
||||
|
||||
if (GATT_GetConnIdIfConnected(p_rcb->gatt_if, p_msg->api_open.remote_bda,
|
||||
&conn_id, p_msg->api_open.transport)) {
|
||||
status = BTA_GATT_ALREADY_OPEN;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_open.server_if);
|
||||
}
|
||||
|
||||
if (p_rcb && p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_OPEN_EVT, (tBTA_GATTS *)&status);
|
||||
}
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_cancel_open
|
||||
**
|
||||
** Description
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_cancel_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb;
|
||||
tBTA_GATT_STATUS status = BTA_GATT_ERROR;
|
||||
UNUSED(p_cb);
|
||||
|
||||
if ((p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_cancel_open.server_if)) != NULL) {
|
||||
if (!GATT_CancelConnect(p_rcb->gatt_if, p_msg->api_cancel_open.remote_bda,
|
||||
p_msg->api_cancel_open.is_direct)) {
|
||||
APPL_TRACE_ERROR("bta_gatts_cancel_open failed for open request");
|
||||
} else {
|
||||
status = BTA_GATT_OK;
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_ERROR("Inavlide server_if=%d", p_msg->api_cancel_open.server_if);
|
||||
}
|
||||
|
||||
if (p_rcb && p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_CANCEL_OPEN_EVT, (tBTA_GATTS *)&status);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_close
|
||||
**
|
||||
** Description
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb;
|
||||
tBTA_GATT_STATUS status = BTA_GATT_ERROR;
|
||||
tGATT_IF gatt_if;
|
||||
BD_ADDR remote_bda;
|
||||
tBTA_GATT_TRANSPORT transport;
|
||||
|
||||
UNUSED(p_cb);
|
||||
|
||||
if (GATT_GetConnectionInfor(p_msg->hdr.layer_specific, &gatt_if, remote_bda, &transport)) {
|
||||
if (GATT_Disconnect(p_msg->hdr.layer_specific) != GATT_SUCCESS) {
|
||||
APPL_TRACE_ERROR("bta_gatts_close fail conn_id=%d", p_msg->hdr.layer_specific);
|
||||
} else {
|
||||
status = BTA_GATT_OK;
|
||||
}
|
||||
|
||||
p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
|
||||
|
||||
if (p_rcb && p_rcb->p_cback) {
|
||||
if (transport == BTA_TRANSPORT_BR_EDR) {
|
||||
bta_sys_conn_close( BTA_ID_GATTS , BTA_ALL_APP_ID, remote_bda);
|
||||
}
|
||||
|
||||
(*p_rcb->p_cback)(BTA_GATTS_CLOSE_EVT, (tBTA_GATTS *)&status);
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_ERROR("Unknown connection ID: %d", p_msg->hdr.layer_specific);
|
||||
}
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_listen
|
||||
**
|
||||
** Description Start or stop listening for LE connection on a GATT server
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb = bta_gatts_find_app_rcb_by_app_if(p_msg->api_listen.server_if);
|
||||
tBTA_GATTS cb_data;
|
||||
UNUSED(p_cb);
|
||||
|
||||
cb_data.reg_oper.status = BTA_GATT_OK;
|
||||
cb_data.reg_oper.server_if = p_msg->api_listen.server_if;
|
||||
|
||||
if (p_rcb == NULL) {
|
||||
APPL_TRACE_ERROR("Unknown GATTS application");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GATT_Listen(p_msg->api_listen.server_if,
|
||||
p_msg->api_listen.start,
|
||||
p_msg->api_listen.remote_bda)) {
|
||||
cb_data.status = BTA_GATT_ERROR;
|
||||
APPL_TRACE_ERROR("bta_gatts_listen Listen failed");
|
||||
}
|
||||
|
||||
if (p_rcb->p_cback) {
|
||||
(*p_rcb->p_cback)(BTA_GATTS_LISTEN_EVT, &cb_data);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_request_cback
|
||||
**
|
||||
** Description GATTS attribute request callback.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_gatts_send_request_cback (UINT16 conn_id,
|
||||
UINT32 trans_id,
|
||||
tGATTS_REQ_TYPE req_type, tGATTS_DATA *p_data)
|
||||
{
|
||||
tBTA_GATTS cb_data;
|
||||
tBTA_GATTS_RCB *p_rcb;
|
||||
tGATT_IF gatt_if;
|
||||
tBTA_GATT_TRANSPORT transport;
|
||||
|
||||
memset(&cb_data, 0 , sizeof(tBTA_GATTS));
|
||||
|
||||
if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport)) {
|
||||
p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
|
||||
|
||||
APPL_TRACE_DEBUG ("bta_gatts_send_request_cback conn_id=%d trans_id=%d req_type=%d",
|
||||
conn_id, trans_id, req_type);
|
||||
|
||||
if (p_rcb && p_rcb->p_cback) {
|
||||
/* if over BR_EDR, inform PM for mode change */
|
||||
if (transport == BTA_TRANSPORT_BR_EDR) {
|
||||
bta_sys_busy(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
|
||||
bta_sys_idle(BTA_ID_GATTS, BTA_ALL_APP_ID, cb_data.req_data.remote_bda);
|
||||
}
|
||||
|
||||
cb_data.req_data.conn_id = conn_id;
|
||||
cb_data.req_data.trans_id = trans_id;
|
||||
cb_data.req_data.p_data = (tBTA_GATTS_REQ_DATA *)p_data;
|
||||
|
||||
(*p_rcb->p_cback)(req_type, &cb_data);
|
||||
} else {
|
||||
APPL_TRACE_ERROR("connection request on gatt_if[%d] is not interested", gatt_if);
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_ERROR("request received on unknown connection ID: %d", conn_id);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_conn_cback
|
||||
**
|
||||
** Description connection callback.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
|
||||
BOOLEAN connected, tGATT_DISCONN_REASON reason,
|
||||
tGATT_TRANSPORT transport)
|
||||
{
|
||||
tBTA_GATTS cb_data;
|
||||
UINT8 evt = connected ? BTA_GATTS_CONNECT_EVT : BTA_GATTS_DISCONNECT_EVT;
|
||||
tBTA_GATTS_RCB *p_reg;
|
||||
|
||||
APPL_TRACE_DEBUG ("bta_gatts_conn_cback gatt_if=%d conn_id=%d connected=%d reason = 0x%04d",
|
||||
gatt_if, conn_id, connected, reason);
|
||||
APPL_TRACE_DEBUG("bta_gatts_conn_cback bda :%02x-%02x-%02x-%02x-%02x-%02x ",
|
||||
bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]);
|
||||
|
||||
bt_bdaddr_t bdaddr;
|
||||
bdcpy(bdaddr.address, bda);
|
||||
/*
|
||||
if (connected)
|
||||
btif_debug_conn_state(bdaddr, BTIF_DEBUG_CONNECTED, GATT_CONN_UNKNOWN);
|
||||
else
|
||||
btif_debug_conn_state(bdaddr, BTIF_DEBUG_DISCONNECTED, reason);
|
||||
*/
|
||||
p_reg = bta_gatts_find_app_rcb_by_app_if(gatt_if);
|
||||
|
||||
if (p_reg && p_reg->p_cback) {
|
||||
/* there is no RM for GATT */
|
||||
if (transport == BTA_TRANSPORT_BR_EDR) {
|
||||
if (connected) {
|
||||
bta_sys_conn_open(BTA_ID_GATTS, BTA_ALL_APP_ID, bda);
|
||||
} else {
|
||||
bta_sys_conn_close( BTA_ID_GATTS , BTA_ALL_APP_ID, bda);
|
||||
}
|
||||
}
|
||||
|
||||
cb_data.conn.conn_id = conn_id;
|
||||
cb_data.conn.server_if = gatt_if;
|
||||
cb_data.conn.reason = reason;
|
||||
cb_data.conn.transport = transport;
|
||||
memcpy(cb_data.conn.remote_bda, bda, BD_ADDR_LEN);
|
||||
(*p_reg->p_cback)(evt, &cb_data);
|
||||
} else {
|
||||
APPL_TRACE_ERROR("bta_gatts_conn_cback server_if=%d not found", gatt_if);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_cong_cback
|
||||
**
|
||||
** Description congestion callback.
|
||||
**
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_gatts_cong_cback (UINT16 conn_id, BOOLEAN congested)
|
||||
{
|
||||
tBTA_GATTS_RCB *p_rcb;
|
||||
tGATT_IF gatt_if;
|
||||
tBTA_GATT_TRANSPORT transport;
|
||||
tBTA_GATTS cb_data;
|
||||
|
||||
if (GATT_GetConnectionInfor(conn_id, &gatt_if, cb_data.req_data.remote_bda, &transport)) {
|
||||
p_rcb = bta_gatts_find_app_rcb_by_app_if(gatt_if);
|
||||
|
||||
if (p_rcb && p_rcb->p_cback) {
|
||||
cb_data.congest.conn_id = conn_id;
|
||||
cb_data.congest.congested = congested;
|
||||
|
||||
(*p_rcb->p_cback)(BTA_GATTS_CONGEST_EVT, &cb_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* BTA_GATT_INCLUDED */
|
||||
558
components/bt/bluedroid/bta/gatt/bta_gatts_api.c
Normal file
558
components/bt/bluedroid/bta/gatt/bta_gatts_api.c
Normal file
@@ -0,0 +1,558 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the implementation of the API for GATT server of BTA.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
|
||||
#if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
|
||||
|
||||
#include <string.h>
|
||||
#include "gki.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_gatt_api.h"
|
||||
#include "bta_gatts_int.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
|
||||
static const tBTA_SYS_REG bta_gatts_reg = {
|
||||
bta_gatts_hdl_event,
|
||||
BTA_GATTS_Disable
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_Disable
|
||||
**
|
||||
** Description This function is called to disable GATTS module
|
||||
**
|
||||
** Parameters None.
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_Disable(void)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if (bta_sys_is_register(BTA_ID_GATTS) == FALSE) {
|
||||
APPL_TRACE_WARNING("GATTS Module not enabled/already disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_GATTS_API_DISABLE_EVT;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
bta_sys_deregister(BTA_ID_GATTS);
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_AppRegister
|
||||
**
|
||||
** Description This function is called to register application callbacks
|
||||
** with BTA GATTS module.
|
||||
**
|
||||
** Parameters p_app_uuid - applicaiton UUID
|
||||
** p_cback - pointer to the application callback function.
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_AppRegister(tBT_UUID *p_app_uuid, tBTA_GATTS_CBACK *p_cback)
|
||||
{
|
||||
tBTA_GATTS_API_REG *p_buf;
|
||||
|
||||
/* register with BTA system manager */
|
||||
if (bta_sys_is_register(BTA_ID_GATTS) == FALSE) {
|
||||
bta_sys_register(BTA_ID_GATTS, &bta_gatts_reg);
|
||||
}
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_REG *) GKI_getbuf(sizeof(tBTA_GATTS_API_REG))) != NULL) {
|
||||
p_buf->hdr.event = BTA_GATTS_API_REG_EVT;
|
||||
|
||||
if (p_app_uuid != NULL) {
|
||||
memcpy(&p_buf->app_uuid, p_app_uuid, sizeof(tBT_UUID));
|
||||
}
|
||||
p_buf->p_cback = p_cback;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_AppDeregister
|
||||
**
|
||||
** Description De-register with GATT Server.
|
||||
**
|
||||
** Parameters app_id: applicatino ID.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_AppDeregister(tBTA_GATTS_IF server_if)
|
||||
{
|
||||
tBTA_GATTS_API_DEREG *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_DEREG *) GKI_getbuf(sizeof(tBTA_GATTS_API_DEREG))) != NULL) {
|
||||
p_buf->hdr.event = BTA_GATTS_API_DEREG_EVT;
|
||||
p_buf->server_if = server_if;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_CreateService
|
||||
**
|
||||
** Description Create a service. When service creation is done, a callback
|
||||
** event BTA_GATTS_CREATE_SRVC_EVT is called to report status
|
||||
** and service ID to the profile. The service ID obtained in
|
||||
** the callback function needs to be used when adding included
|
||||
** service and characteristics/descriptors into the service.
|
||||
**
|
||||
** Parameters app_id: Profile ID this service is belonged to.
|
||||
** p_service_uuid: service UUID.
|
||||
** inst: instance ID number of this service.
|
||||
** num_handle: numble of handle requessted for this service.
|
||||
** is_primary: is this service a primary one or not.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_CreateService(tBTA_GATTS_IF server_if, tBT_UUID *p_service_uuid, UINT8 inst,
|
||||
UINT16 num_handle, BOOLEAN is_primary)
|
||||
{
|
||||
tBTA_GATTS_API_CREATE_SRVC *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_CREATE_SRVC *) GKI_getbuf(sizeof(tBTA_GATTS_API_CREATE_SRVC))) != NULL) {
|
||||
p_buf->hdr.event = BTA_GATTS_API_CREATE_SRVC_EVT;
|
||||
|
||||
p_buf->server_if = server_if;
|
||||
p_buf->inst = inst;
|
||||
memcpy(&p_buf->service_uuid, p_service_uuid, sizeof(tBT_UUID));
|
||||
p_buf->num_handle = num_handle;
|
||||
p_buf->is_pri = is_primary;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_AddIncludeService
|
||||
**
|
||||
** Description This function is called to add an included service. After included
|
||||
** service is included, a callback event BTA_GATTS_ADD_INCL_SRVC_EVT
|
||||
** is reported the included service ID.
|
||||
**
|
||||
** Parameters service_id: service ID to which this included service is to
|
||||
** be added.
|
||||
** included_service_id: the service ID to be included.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_AddIncludeService(UINT16 service_id, UINT16 included_service_id)
|
||||
{
|
||||
tBTA_GATTS_API_ADD_INCL_SRVC *p_buf;
|
||||
|
||||
if ((p_buf =
|
||||
(tBTA_GATTS_API_ADD_INCL_SRVC *) GKI_getbuf(sizeof(tBTA_GATTS_API_ADD_INCL_SRVC)))
|
||||
!= NULL) {
|
||||
p_buf->hdr.event = BTA_GATTS_API_ADD_INCL_SRVC_EVT;
|
||||
|
||||
p_buf->hdr.layer_specific = service_id;
|
||||
p_buf->included_service_id = included_service_id;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_AddCharacteristic
|
||||
**
|
||||
** Description This function is called to add a characteristic into a service.
|
||||
**
|
||||
** Parameters service_id: service ID to which this included service is to
|
||||
** be added.
|
||||
** p_char_uuid : Characteristic UUID.
|
||||
** perm : Characteristic value declaration attribute permission.
|
||||
** property : Characteristic Properties
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_AddCharacteristic (UINT16 service_id, tBT_UUID *p_char_uuid,
|
||||
tBTA_GATT_PERM perm, tBTA_GATT_CHAR_PROP property)
|
||||
{
|
||||
tBTA_GATTS_API_ADD_CHAR *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_ADD_CHAR *) GKI_getbuf(sizeof(tBTA_GATTS_API_ADD_CHAR))) != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_GATTS_API_ADD_CHAR));
|
||||
|
||||
p_buf->hdr.event = BTA_GATTS_API_ADD_CHAR_EVT;
|
||||
p_buf->hdr.layer_specific = service_id;
|
||||
p_buf->perm = perm;
|
||||
p_buf->property = property;
|
||||
|
||||
if (p_char_uuid) {
|
||||
memcpy(&p_buf->char_uuid, p_char_uuid, sizeof(tBT_UUID));
|
||||
}
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_AddCharDescriptor
|
||||
**
|
||||
** Description This function is called to add characteristic descriptor. When
|
||||
** it's done, a callback event BTA_GATTS_ADD_DESCR_EVT is called
|
||||
** to report the status and an ID number for this descriptor.
|
||||
**
|
||||
** Parameters service_id: service ID to which this charatceristic descriptor is to
|
||||
** be added.
|
||||
** perm: descriptor access permission.
|
||||
** p_descr_uuid: descriptor UUID.
|
||||
**
|
||||
** Returns returns status.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_AddCharDescriptor (UINT16 service_id,
|
||||
tBTA_GATT_PERM perm,
|
||||
tBT_UUID *p_descr_uuid)
|
||||
{
|
||||
tBTA_GATTS_API_ADD_DESCR *p_buf;
|
||||
UINT16 len = sizeof(tBTA_GATTS_API_ADD_DESCR);
|
||||
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_ADD_DESCR *) GKI_getbuf(len)) != NULL) {
|
||||
memset(p_buf, 0, len);
|
||||
|
||||
p_buf->hdr.event = BTA_GATTS_API_ADD_DESCR_EVT;
|
||||
p_buf->hdr.layer_specific = service_id;
|
||||
p_buf->perm = perm;
|
||||
|
||||
if (p_descr_uuid) {
|
||||
memcpy(&p_buf->descr_uuid, p_descr_uuid, sizeof(tBT_UUID));
|
||||
}
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_DeleteService
|
||||
**
|
||||
** Description This function is called to delete a service. When this is done,
|
||||
** a callback event BTA_GATTS_DELETE_EVT is report with the status.
|
||||
**
|
||||
** Parameters service_id: service_id to be deleted.
|
||||
**
|
||||
** Returns returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_DeleteService(UINT16 service_id)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_GATTS_API_DEL_SRVC_EVT;
|
||||
|
||||
p_buf->layer_specific = service_id;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_StartService
|
||||
**
|
||||
** Description This function is called to start a service.
|
||||
**
|
||||
** Parameters service_id: the service ID to be started.
|
||||
** sup_transport: supported trasnport.
|
||||
**
|
||||
** Returns None.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_StartService(UINT16 service_id, tBTA_GATT_TRANSPORT sup_transport)
|
||||
{
|
||||
tBTA_GATTS_API_START *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_START *) GKI_getbuf(sizeof(tBTA_GATTS_API_START))) != NULL) {
|
||||
p_buf->hdr.event = BTA_GATTS_API_START_SRVC_EVT;
|
||||
|
||||
p_buf->hdr.layer_specific = service_id;
|
||||
p_buf->transport = sup_transport;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_StopService
|
||||
**
|
||||
** Description This function is called to stop a service.
|
||||
**
|
||||
** Parameters service_id - service to be topped.
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_StopService(UINT16 service_id)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_GATTS_API_STOP_SRVC_EVT;
|
||||
|
||||
p_buf->layer_specific = service_id;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_HandleValueIndication
|
||||
**
|
||||
** Description This function is called to read a characteristics descriptor.
|
||||
**
|
||||
** Parameters bda - remote device bd address to indicate.
|
||||
** attr_id - attribute ID to indicate.
|
||||
** data_len - indicate data length.
|
||||
** p_data: data to indicate.
|
||||
** need_confirm - if this indication expects a confirmation or not.
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_HandleValueIndication (UINT16 conn_id, UINT16 attr_id, UINT16 data_len,
|
||||
UINT8 *p_data, BOOLEAN need_confirm)
|
||||
{
|
||||
tBTA_GATTS_API_INDICATION *p_buf;
|
||||
UINT16 len = sizeof(tBTA_GATTS_API_INDICATION);
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_INDICATION *) GKI_getbuf(len)) != NULL) {
|
||||
memset(p_buf, 0, len);
|
||||
|
||||
p_buf->hdr.event = BTA_GATTS_API_INDICATION_EVT;
|
||||
p_buf->hdr.layer_specific = conn_id;
|
||||
p_buf->attr_id = attr_id;
|
||||
p_buf->need_confirm = need_confirm;
|
||||
|
||||
if (data_len > 0 && p_data != NULL) {
|
||||
p_buf->len = data_len;
|
||||
memcpy(p_buf->value, p_data, data_len);
|
||||
|
||||
}
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_SendRsp
|
||||
**
|
||||
** Description This function is called to send a response to a request.
|
||||
**
|
||||
** Parameters conn_id - connection identifier.
|
||||
** trans_id - transaction ID.
|
||||
** status - response status
|
||||
** p_msg - response data.
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_SendRsp (UINT16 conn_id, UINT32 trans_id,
|
||||
tBTA_GATT_STATUS status, tBTA_GATTS_RSP *p_msg)
|
||||
{
|
||||
tBTA_GATTS_API_RSP *p_buf;
|
||||
UINT16 len = sizeof(tBTA_GATTS_API_RSP) + sizeof(tBTA_GATTS_RSP);
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_RSP *) GKI_getbuf(len)) != NULL) {
|
||||
memset(p_buf, 0, len);
|
||||
|
||||
p_buf->hdr.event = BTA_GATTS_API_RSP_EVT;
|
||||
p_buf->hdr.layer_specific = conn_id;
|
||||
p_buf->trans_id = trans_id;
|
||||
p_buf->status = status;
|
||||
|
||||
if (p_msg != NULL) {
|
||||
p_buf->p_rsp = (tBTA_GATTS_RSP *)(p_buf + 1);
|
||||
memcpy(p_buf->p_rsp, p_msg, sizeof(tBTA_GATTS_RSP));
|
||||
}
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_Open
|
||||
**
|
||||
** Description Open a direct open connection or add a background auto connection
|
||||
** bd address
|
||||
**
|
||||
** Parameters server_if: server interface.
|
||||
** remote_bda: remote device BD address.
|
||||
** is_direct: direct connection or background auto connection
|
||||
** transport : Transport on which GATT connection to be opened (BR/EDR or LE)
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_Open(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct,
|
||||
tBTA_GATT_TRANSPORT transport)
|
||||
{
|
||||
tBTA_GATTS_API_OPEN *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_OPEN *) GKI_getbuf(sizeof(tBTA_GATTS_API_OPEN))) != NULL) {
|
||||
p_buf->hdr.event = BTA_GATTS_API_OPEN_EVT;
|
||||
p_buf->server_if = server_if;
|
||||
p_buf->is_direct = is_direct;
|
||||
p_buf->transport = transport;
|
||||
memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_CancelOpen
|
||||
**
|
||||
** Description Cancel a direct open connection or remove a background auto connection
|
||||
** bd address
|
||||
**
|
||||
** Parameters server_if: server interface.
|
||||
** remote_bda: remote device BD address.
|
||||
** is_direct: direct connection or background auto connection
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_CancelOpen(tBTA_GATTS_IF server_if, BD_ADDR remote_bda, BOOLEAN is_direct)
|
||||
{
|
||||
tBTA_GATTS_API_CANCEL_OPEN *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_CANCEL_OPEN *) GKI_getbuf(sizeof(tBTA_GATTS_API_CANCEL_OPEN))) != NULL) {
|
||||
p_buf->hdr.event = BTA_GATTS_API_CANCEL_OPEN_EVT;
|
||||
p_buf->server_if = server_if;
|
||||
p_buf->is_direct = is_direct;
|
||||
memcpy(p_buf->remote_bda, remote_bda, BD_ADDR_LEN);
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_Close
|
||||
**
|
||||
** Description Close a connection a remote device.
|
||||
**
|
||||
** Parameters conn_id: connection ID to be closed.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_Close(UINT16 conn_id)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_GATTS_API_CLOSE_EVT;
|
||||
p_buf->layer_specific = conn_id;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_GATTS_Listen
|
||||
**
|
||||
** Description Start advertisement to listen for connection request for a
|
||||
** GATT server
|
||||
**
|
||||
** Parameters server_if: server interface.
|
||||
** start: to start or stop listening for connection
|
||||
** remote_bda: remote device BD address, if listen to all device
|
||||
** use NULL.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTS_Listen(tBTA_GATTS_IF server_if, BOOLEAN start, BD_ADDR_PTR target_bda)
|
||||
{
|
||||
tBTA_GATTS_API_LISTEN *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_GATTS_API_LISTEN *) GKI_getbuf((UINT16)(sizeof(tBTA_GATTS_API_LISTEN) + BD_ADDR_LEN))) != NULL) {
|
||||
p_buf->hdr.event = BTA_GATTS_API_LISTEN_EVT;
|
||||
|
||||
p_buf->server_if = server_if;
|
||||
p_buf->start = start;
|
||||
|
||||
if (target_bda) {
|
||||
p_buf->remote_bda = (UINT8 *)(p_buf + 1);
|
||||
memcpy(p_buf->remote_bda, target_bda, BD_ADDR_LEN);
|
||||
} else {
|
||||
p_buf->remote_bda = NULL;
|
||||
}
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* BTA_GATT_INCLUDED */
|
||||
138
components/bt/bluedroid/bta/gatt/bta_gatts_main.c
Normal file
138
components/bt/bluedroid/bta/gatt/bta_gatts_main.c
Normal file
@@ -0,0 +1,138 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the GATT server main functions and state machine.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
|
||||
#if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "bta_gatts_int.h"
|
||||
#include "gki.h"
|
||||
|
||||
/* type for service building action functions */
|
||||
typedef void (*tBTA_GATTS_SRVC_ACT)(tBTA_GATTS_SRVC_CB *p_rcb, tBTA_GATTS_DATA *p_data);
|
||||
|
||||
/* service building action function list */
|
||||
const tBTA_GATTS_SRVC_ACT bta_gatts_srvc_build_act[] = {
|
||||
bta_gatts_add_include_srvc,
|
||||
bta_gatts_add_char,
|
||||
bta_gatts_add_char_descr,
|
||||
bta_gatts_delete_service,
|
||||
bta_gatts_start_service,
|
||||
bta_gatts_stop_service,
|
||||
};
|
||||
|
||||
/* GATTS control block */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
tBTA_GATTS_CB bta_gatts_cb;
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_hdl_event
|
||||
**
|
||||
** Description BTA GATT server main event handling function.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gatts_hdl_event(BT_HDR *p_msg)
|
||||
{
|
||||
tBTA_GATTS_CB *p_cb = &bta_gatts_cb;
|
||||
tBTA_GATTS_SRVC_CB *p_srvc_cb = NULL;
|
||||
|
||||
switch (p_msg->event) {
|
||||
case BTA_GATTS_API_DISABLE_EVT:
|
||||
bta_gatts_api_disable(p_cb);
|
||||
break;
|
||||
|
||||
case BTA_GATTS_API_REG_EVT:
|
||||
bta_gatts_register(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTS_INT_START_IF_EVT:
|
||||
bta_gatts_start_if(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTS_API_DEREG_EVT:
|
||||
bta_gatts_deregister(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTS_API_CREATE_SRVC_EVT:
|
||||
bta_gatts_create_srvc(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTS_API_INDICATION_EVT:
|
||||
bta_gatts_indicate_handle(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTS_API_OPEN_EVT:
|
||||
bta_gatts_open(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTS_API_CANCEL_OPEN_EVT:
|
||||
bta_gatts_cancel_open(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTS_API_CLOSE_EVT:
|
||||
bta_gatts_close(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTS_API_RSP_EVT:
|
||||
bta_gatts_send_rsp(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_GATTS_API_LISTEN_EVT:
|
||||
bta_gatts_listen(p_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
|
||||
case BTA_GATTS_API_ADD_INCL_SRVC_EVT:
|
||||
case BTA_GATTS_API_ADD_CHAR_EVT:
|
||||
case BTA_GATTS_API_ADD_DESCR_EVT:
|
||||
case BTA_GATTS_API_DEL_SRVC_EVT:
|
||||
case BTA_GATTS_API_START_SRVC_EVT:
|
||||
case BTA_GATTS_API_STOP_SRVC_EVT:
|
||||
|
||||
p_srvc_cb = bta_gatts_find_srvc_cb_by_srvc_id(p_cb,
|
||||
((tBTA_GATTS_DATA *)p_msg)->api_add_incl_srvc.hdr.layer_specific);
|
||||
|
||||
if (p_srvc_cb != NULL) {
|
||||
bta_gatts_srvc_build_act[p_msg->event - BTA_GATTS_API_ADD_INCL_SRVC_EVT](p_srvc_cb, (tBTA_GATTS_DATA *) p_msg);
|
||||
} else {
|
||||
APPL_TRACE_ERROR("service not created");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
#endif /* BTA_GATT_INCLUDED */
|
||||
225
components/bt/bluedroid/bta/gatt/bta_gatts_utils.c
Normal file
225
components/bt/bluedroid/bta/gatt/bta_gatts_utils.c
Normal file
@@ -0,0 +1,225 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the GATT client utility function.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
|
||||
#if defined(BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE)
|
||||
|
||||
#include <string.h>
|
||||
#include "utl.h"
|
||||
#include "gki.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_gatts_int.h"
|
||||
|
||||
static const UINT8 base_uuid[LEN_UUID_128] = {0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80,
|
||||
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatt_convert_uuid16_to_uuid128
|
||||
**
|
||||
** Description Convert a 16 bits UUID to be an standard 128 bits one.
|
||||
**
|
||||
** Returns TRUE if two uuid match; FALSE otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_gatt_convert_uuid16_to_uuid128(UINT8 uuid_128[LEN_UUID_128], UINT16 uuid_16)
|
||||
{
|
||||
UINT8 *p = &uuid_128[LEN_UUID_128 - 4];
|
||||
|
||||
memcpy (uuid_128, base_uuid, LEN_UUID_128);
|
||||
|
||||
UINT16_TO_STREAM(p, uuid_16);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_alloc_srvc_cb
|
||||
**
|
||||
** Description allocate a service control block.
|
||||
**
|
||||
** Returns pointer to the control block, or otherwise NULL when failed.
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT8 bta_gatts_alloc_srvc_cb(tBTA_GATTS_CB *p_cb, UINT8 rcb_idx)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < BTA_GATTS_MAX_SRVC_NUM; i ++) {
|
||||
if (!p_cb->srvc_cb[i].in_use) {
|
||||
p_cb->srvc_cb[i].in_use = TRUE;
|
||||
p_cb->srvc_cb[i].rcb_idx = rcb_idx;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return BTA_GATTS_INVALID_APP;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_find_app_rcb_by_app_if
|
||||
**
|
||||
** Description find the index of the application control block by app ID.
|
||||
**
|
||||
** Returns pointer to the control block if success, otherwise NULL
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTS_RCB *bta_gatts_find_app_rcb_by_app_if(tBTA_GATTS_IF server_if)
|
||||
{
|
||||
UINT8 i;
|
||||
tBTA_GATTS_RCB *p_reg;
|
||||
|
||||
for (i = 0, p_reg = bta_gatts_cb.rcb; i < BTA_GATTS_MAX_APP_NUM; i ++, p_reg++) {
|
||||
if (p_reg->in_use && p_reg->gatt_if == server_if) {
|
||||
return p_reg;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_find_app_rcb_idx_by_app_if
|
||||
**
|
||||
** Description find the index of the application control block by app ID.
|
||||
**
|
||||
** Returns index of the control block, or BTA_GATTS_INVALID_APP if failed.
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
||||
UINT8 bta_gatts_find_app_rcb_idx_by_app_if(tBTA_GATTS_CB *p_cb, tBTA_GATTS_IF server_if)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < BTA_GATTS_MAX_APP_NUM; i ++) {
|
||||
if (p_cb->rcb[i].in_use && p_cb->rcb[i].gatt_if == server_if) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return BTA_GATTS_INVALID_APP;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_find_srvc_cb_by_srvc_id
|
||||
**
|
||||
** Description find the service control block by service ID.
|
||||
**
|
||||
** Returns pointer to the rcb.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTS_SRVC_CB *bta_gatts_find_srvc_cb_by_srvc_id(tBTA_GATTS_CB *p_cb, UINT16 service_id)
|
||||
{
|
||||
UINT8 i;
|
||||
APPL_TRACE_DEBUG("bta_gatts_find_srvc_cb_by_srvc_id service_id=%d", service_id);
|
||||
for (i = 0; i < BTA_GATTS_MAX_SRVC_NUM; i ++) {
|
||||
if (p_cb->srvc_cb[i].in_use &&
|
||||
p_cb->srvc_cb[i].service_id == service_id) {
|
||||
APPL_TRACE_DEBUG("bta_gatts_find_srvc_cb_by_srvc_id found service cb index =%d", i);
|
||||
return &p_cb->srvc_cb[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_find_srvc_cb_by_attr_id
|
||||
**
|
||||
** Description find the service control block by attribute ID.
|
||||
**
|
||||
** Returns pointer to the rcb.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_GATTS_SRVC_CB *bta_gatts_find_srvc_cb_by_attr_id(tBTA_GATTS_CB *p_cb, UINT16 attr_id)
|
||||
{
|
||||
UINT8 i;
|
||||
|
||||
for (i = 0; i < (BTA_GATTS_MAX_SRVC_NUM); i ++) {
|
||||
if (/* middle service */
|
||||
(i < (BTA_GATTS_MAX_SRVC_NUM - 1) &&
|
||||
p_cb->srvc_cb[i].in_use &&
|
||||
p_cb->srvc_cb[i + 1].in_use &&
|
||||
attr_id >= p_cb->srvc_cb[i].service_id &&
|
||||
attr_id < p_cb->srvc_cb[i + 1].service_id) ||
|
||||
/* last active service */
|
||||
(i < (BTA_GATTS_MAX_SRVC_NUM - 1) &&
|
||||
p_cb->srvc_cb[i].in_use &&
|
||||
!p_cb->srvc_cb[i + 1].in_use &&
|
||||
attr_id >= p_cb->srvc_cb[i].service_id) ||
|
||||
/* last service incb */
|
||||
(i == (BTA_GATTS_MAX_SRVC_NUM - 1) &&
|
||||
attr_id >= p_cb->srvc_cb[i].service_id)
|
||||
) {
|
||||
return &p_cb->srvc_cb[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_uuid_compare
|
||||
**
|
||||
** Description Compare two UUID to see if they are the same.
|
||||
**
|
||||
** Returns TRUE if two uuid match; FALSE otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_gatts_uuid_compare(tBT_UUID tar, tBT_UUID src)
|
||||
{
|
||||
UINT8 su[LEN_UUID_128], tu[LEN_UUID_128];
|
||||
UINT8 *ps, *pt;
|
||||
|
||||
/* any of the UUID is unspecified */
|
||||
if (src.len == 0 || tar.len == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* If both are 16-bit, we can do a simple compare */
|
||||
if (src.len == 2 && tar.len == 2) {
|
||||
return src.uu.uuid16 == tar.uu.uuid16;
|
||||
}
|
||||
|
||||
/* One or both of the UUIDs is 128-bit */
|
||||
if (src.len == LEN_UUID_16) {
|
||||
/* convert a 16 bits UUID to 128 bits value */
|
||||
bta_gatt_convert_uuid16_to_uuid128(su, src.uu.uuid16);
|
||||
ps = su;
|
||||
} else {
|
||||
ps = src.uu.uuid128;
|
||||
}
|
||||
|
||||
if (tar.len == LEN_UUID_16) {
|
||||
/* convert a 16 bits UUID to 128 bits value */
|
||||
bta_gatt_convert_uuid16_to_uuid128(tu, tar.uu.uuid16);
|
||||
pt = tu;
|
||||
} else {
|
||||
pt = tar.uu.uuid128;
|
||||
}
|
||||
|
||||
return (memcmp(ps, pt, LEN_UUID_128) == 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
1251
components/bt/bluedroid/bta/hh/bta_hh_act.c
Normal file
1251
components/bt/bluedroid/bta/hh/bta_hh_act.c
Normal file
File diff suppressed because it is too large
Load Diff
478
components/bt/bluedroid/bta/hh/bta_hh_api.c
Normal file
478
components/bt/bluedroid/bta/hh/bta_hh_api.c
Normal file
@@ -0,0 +1,478 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the HID HOST API in the subsystem of BTA.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
|
||||
#if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bta_hh_api.h"
|
||||
#include "bta_hh_int.h"
|
||||
#include "l2c_api.h"
|
||||
#include "utl.h"
|
||||
|
||||
#define LOG_TAG "bt_bta_hh"
|
||||
#include "osi/include/log.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
|
||||
static const tBTA_SYS_REG bta_hh_reg = {
|
||||
bta_hh_hdl_event,
|
||||
BTA_HhDisable
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhEnable
|
||||
**
|
||||
** Description Enable the HID host. This function must be called before
|
||||
** any other functions in the HID host API are called. When the
|
||||
** enable operation is complete the callback function will be
|
||||
** called with BTA_HH_ENABLE_EVT.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhEnable(tBTA_SEC sec_mask, tBTA_HH_CBACK *p_cback)
|
||||
{
|
||||
tBTA_HH_API_ENABLE *p_buf;
|
||||
|
||||
/* register with BTA system manager */
|
||||
bta_sys_register(BTA_ID_HH, &bta_hh_reg);
|
||||
|
||||
LOG_INFO("%s sec_mask:0x%x p_cback:%p", __func__, sec_mask, p_cback);
|
||||
p_buf = (tBTA_HH_API_ENABLE *)GKI_getbuf((UINT16)sizeof(tBTA_HH_API_ENABLE));
|
||||
|
||||
if (p_buf != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_HH_API_ENABLE));
|
||||
|
||||
p_buf->hdr.event = BTA_HH_API_ENABLE_EVT;
|
||||
p_buf->p_cback = p_cback;
|
||||
p_buf->sec_mask = sec_mask;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhDisable
|
||||
**
|
||||
** Description Disable the HID host. If the server is currently
|
||||
** connected, the connection will be closed.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhDisable(void)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
bta_sys_deregister(BTA_ID_HH);
|
||||
if ((p_buf = (BT_HDR *)GKI_getbuf(sizeof(BT_HDR))) != NULL) {
|
||||
p_buf->event = BTA_HH_API_DISABLE_EVT;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhClose
|
||||
**
|
||||
** Description Disconnect a connection.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhClose(UINT8 dev_handle)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if ((p_buf = (BT_HDR *)GKI_getbuf((UINT16)sizeof(BT_HDR))) != NULL) {
|
||||
memset(p_buf, 0, sizeof(BT_HDR));
|
||||
p_buf->event = BTA_HH_API_CLOSE_EVT;
|
||||
p_buf->layer_specific = (UINT16) dev_handle;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhOpen
|
||||
**
|
||||
** Description Connect to a device of specified BD address in specified
|
||||
** protocol mode and security level.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhOpen(BD_ADDR dev_bda, tBTA_HH_PROTO_MODE mode, tBTA_SEC sec_mask)
|
||||
{
|
||||
tBTA_HH_API_CONN *p_buf;
|
||||
|
||||
p_buf = (tBTA_HH_API_CONN *)GKI_getbuf((UINT16)sizeof(tBTA_HH_API_CONN));
|
||||
|
||||
if (p_buf != NULL) {
|
||||
memset((void *)p_buf, 0, sizeof(tBTA_HH_API_CONN));
|
||||
|
||||
p_buf->hdr.event = BTA_HH_API_OPEN_EVT;
|
||||
p_buf->hdr.layer_specific = BTA_HH_INVALID_HANDLE;
|
||||
p_buf->sec_mask = sec_mask;
|
||||
p_buf->mode = mode;
|
||||
bdcpy(p_buf->bd_addr, dev_bda);
|
||||
|
||||
bta_sys_sendmsg((void *)p_buf);
|
||||
} else {
|
||||
APPL_TRACE_ERROR("No resource to send HID host Connect request.");
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_snd_write_dev
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_hh_snd_write_dev(UINT8 dev_handle, UINT8 t_type, UINT8 param,
|
||||
UINT16 data, UINT8 rpt_id, BT_HDR *p_data)
|
||||
{
|
||||
tBTA_HH_CMD_DATA *p_buf;
|
||||
UINT16 len = (UINT16) (sizeof(tBTA_HH_CMD_DATA) );
|
||||
|
||||
if ((p_buf = (tBTA_HH_CMD_DATA *)GKI_getbuf(len)) != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_HH_CMD_DATA));
|
||||
|
||||
p_buf->hdr.event = BTA_HH_API_WRITE_DEV_EVT;
|
||||
p_buf->hdr.layer_specific = (UINT16) dev_handle;
|
||||
p_buf->t_type = t_type;
|
||||
p_buf->data = data;
|
||||
p_buf->param = param;
|
||||
p_buf->p_data = p_data;
|
||||
p_buf->rpt_id = rpt_id;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSetReport
|
||||
**
|
||||
** Description send SET_REPORT to device.
|
||||
**
|
||||
** Parameter dev_handle: device handle
|
||||
** r_type: report type, could be BTA_HH_RPTT_OUTPUT or
|
||||
** BTA_HH_RPTT_FEATURE.
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhSetReport(UINT8 dev_handle, tBTA_HH_RPT_TYPE r_type, BT_HDR *p_data)
|
||||
{
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_SET_REPORT, r_type, 0, 0, p_data);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetReport
|
||||
**
|
||||
** Description Send a GET_REPORT to HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhGetReport(UINT8 dev_handle, tBTA_HH_RPT_TYPE r_type, UINT8 rpt_id, UINT16 buf_size)
|
||||
{
|
||||
UINT8 param = (buf_size) ? (r_type | 0x08) : r_type;
|
||||
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_GET_REPORT, param,
|
||||
buf_size, rpt_id, NULL);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSetProtoMode
|
||||
**
|
||||
** Description This function set the protocol mode at specified HID handle
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhSetProtoMode(UINT8 dev_handle, tBTA_HH_PROTO_MODE p_type)
|
||||
{
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_SET_PROTOCOL, (UINT8)p_type,
|
||||
0, 0, NULL);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetProtoMode
|
||||
**
|
||||
** Description This function get protocol mode information.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhGetProtoMode(UINT8 dev_handle)
|
||||
{
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_GET_PROTOCOL, 0, 0, 0, NULL);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSetIdle
|
||||
**
|
||||
** Description send SET_IDLE to device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhSetIdle(UINT8 dev_handle, UINT16 idle_rate)
|
||||
{
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_SET_IDLE, 0, idle_rate, 0, NULL);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetIdle
|
||||
**
|
||||
** Description Send a GET_IDLE from HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhGetIdle(UINT8 dev_handle)
|
||||
{
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_GET_IDLE, 0, 0, 0, NULL);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSendCtrl
|
||||
**
|
||||
** Description Send a control command to HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhSendCtrl(UINT8 dev_handle, tBTA_HH_TRANS_CTRL_TYPE c_type)
|
||||
{
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_CONTROL, (UINT8)c_type, 0, 0, NULL);
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSendData
|
||||
**
|
||||
** Description This function send DATA transaction to HID device.
|
||||
**
|
||||
** Parameter dev_handle: device handle
|
||||
** dev_bda: remote device address
|
||||
** p_data: data to be sent in the DATA transaction; or
|
||||
** the data to be write into the Output Report of a LE HID
|
||||
** device. The report is identified the report ID which is
|
||||
** the value of the byte (UINT8 *)(p_buf + 1) + p_buf->offset.
|
||||
** p_data->layer_specific needs to be set to the report type,
|
||||
** it can be OUTPUT report, or FEATURE report.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhSendData(UINT8 dev_handle, BD_ADDR dev_bda, BT_HDR *p_data)
|
||||
{
|
||||
UNUSED(dev_bda);
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
if (p_data->layer_specific != BTA_HH_RPTT_OUTPUT) {
|
||||
APPL_TRACE_ERROR("ERROR! Wrong report type! Write Command only valid for output report!");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
bta_hh_snd_write_dev(dev_handle, HID_TRANS_DATA, (UINT8)p_data->layer_specific, 0, 0, p_data);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetDscpInfo
|
||||
**
|
||||
** Description Get HID device report descriptor
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhGetDscpInfo(UINT8 dev_handle)
|
||||
{
|
||||
BT_HDR *p_buf;
|
||||
|
||||
if ((p_buf = (BT_HDR *)GKI_getbuf((UINT16)sizeof(BT_HDR))) != NULL) {
|
||||
memset(p_buf, 0, sizeof(BT_HDR));
|
||||
p_buf->event = BTA_HH_API_GET_DSCP_EVT;
|
||||
p_buf->layer_specific = (UINT16) dev_handle;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhAddDev
|
||||
**
|
||||
** Description Add a virtually cabled device into HID-Host device list
|
||||
** to manage and assign a device handle for future API call,
|
||||
** host applciation call this API at start-up to initialize its
|
||||
** virtually cabled devices.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhAddDev(BD_ADDR bda, tBTA_HH_ATTR_MASK attr_mask, UINT8 sub_class,
|
||||
UINT8 app_id, tBTA_HH_DEV_DSCP_INFO dscp_info)
|
||||
{
|
||||
tBTA_HH_MAINT_DEV *p_buf;
|
||||
UINT16 len = sizeof(tBTA_HH_MAINT_DEV) + dscp_info.descriptor.dl_len;
|
||||
|
||||
p_buf = (tBTA_HH_MAINT_DEV *)GKI_getbuf(len);
|
||||
|
||||
if (p_buf != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_HH_MAINT_DEV));
|
||||
|
||||
p_buf->hdr.event = BTA_HH_API_MAINT_DEV_EVT;
|
||||
p_buf->sub_event = BTA_HH_ADD_DEV_EVT;
|
||||
p_buf->hdr.layer_specific = BTA_HH_INVALID_HANDLE;
|
||||
|
||||
p_buf->attr_mask = (UINT16) attr_mask;
|
||||
p_buf->sub_class = sub_class;
|
||||
p_buf->app_id = app_id;
|
||||
bdcpy(p_buf->bda, bda);
|
||||
|
||||
memcpy(&p_buf->dscp_info, &dscp_info, sizeof(tBTA_HH_DEV_DSCP_INFO));
|
||||
if ( dscp_info.descriptor.dl_len != 0 && dscp_info.descriptor.dsc_list) {
|
||||
p_buf->dscp_info.descriptor.dl_len = dscp_info.descriptor.dl_len;
|
||||
p_buf->dscp_info.descriptor.dsc_list = (UINT8 *)(p_buf + 1);
|
||||
memcpy(p_buf->dscp_info.descriptor.dsc_list, dscp_info.descriptor.dsc_list, dscp_info.descriptor.dl_len);
|
||||
} else {
|
||||
p_buf->dscp_info.descriptor.dsc_list = NULL;
|
||||
p_buf->dscp_info.descriptor.dl_len = 0;
|
||||
}
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhRemoveDev
|
||||
**
|
||||
** Description Remove a device from the HID host devices list.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhRemoveDev(UINT8 dev_handle )
|
||||
{
|
||||
tBTA_HH_MAINT_DEV *p_buf;
|
||||
|
||||
p_buf = (tBTA_HH_MAINT_DEV *)GKI_getbuf((UINT16)sizeof(tBTA_HH_MAINT_DEV));
|
||||
|
||||
if (p_buf != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_HH_MAINT_DEV));
|
||||
|
||||
p_buf->hdr.event = BTA_HH_API_MAINT_DEV_EVT;
|
||||
p_buf->sub_event = BTA_HH_RMV_DEV_EVT;
|
||||
p_buf->hdr.layer_specific = (UINT16) dev_handle;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
#if BTA_HH_LE_INCLUDED == TRUE
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhUpdateLeScanParam
|
||||
**
|
||||
** Description Update the scan paramteters if connected to a LE hid device as
|
||||
** report host.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhUpdateLeScanParam(UINT8 dev_handle, UINT16 scan_int, UINT16 scan_win)
|
||||
{
|
||||
tBTA_HH_SCPP_UPDATE *p_buf;
|
||||
|
||||
p_buf = (tBTA_HH_SCPP_UPDATE *)GKI_getbuf((UINT16)sizeof(tBTA_HH_SCPP_UPDATE));
|
||||
|
||||
if (p_buf != NULL) {
|
||||
memset(p_buf, 0, sizeof(tBTA_HH_SCPP_UPDATE));
|
||||
|
||||
p_buf->hdr.event = BTA_HH_API_SCPP_UPDATE_EVT;
|
||||
p_buf->hdr.layer_specific = (UINT16) dev_handle;
|
||||
p_buf->scan_int = scan_int;
|
||||
p_buf->scan_win = scan_win;
|
||||
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*******************************************************************************/
|
||||
/* Utility Function */
|
||||
/*******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhParseBootRpt
|
||||
**
|
||||
** Description This utility function parse a boot mode report.
|
||||
** For keyboard report, report data will carry the keycode max
|
||||
** up to 6 key press in one report. Application need to convert
|
||||
** the keycode into keypress character according to keyboard
|
||||
** language.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_HhParseBootRpt(tBTA_HH_BOOT_RPT *p_data, UINT8 *p_report,
|
||||
UINT16 report_len)
|
||||
{
|
||||
p_data->dev_type = BTA_HH_DEVT_UNKNOWN;
|
||||
|
||||
if (p_report) {
|
||||
/* first byte is report ID */
|
||||
switch (p_report[0]) {
|
||||
case BTA_HH_KEYBD_RPT_ID: /* key board report ID */
|
||||
p_data->dev_type = p_report[0];
|
||||
bta_hh_parse_keybd_rpt(p_data, p_report + 1, (UINT16)(report_len - 1));
|
||||
break;
|
||||
|
||||
case BTA_HH_MOUSE_RPT_ID: /* mouse report ID */
|
||||
p_data->dev_type = p_report[0];
|
||||
bta_hh_parse_mice_rpt(p_data, p_report + 1, (UINT16)(report_len - 1));
|
||||
break;
|
||||
|
||||
default:
|
||||
APPL_TRACE_DEBUG("Unknown boot report: %d", p_report[0]);;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* BTA_HH_INCLUDED */
|
||||
60
components/bt/bluedroid/bta/hh/bta_hh_cfg.c
Normal file
60
components/bt/bluedroid/bta/hh/bta_hh_cfg.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains compile-time configurable constants for the BTA Hid
|
||||
* Host.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
#include "bta_hh_api.h"
|
||||
|
||||
/* max number of device types supported by BTA */
|
||||
#define BTA_HH_MAX_DEVT_SPT 9
|
||||
|
||||
/* size of database for service discovery */
|
||||
#ifndef BTA_HH_DISC_BUF_SIZE
|
||||
#define BTA_HH_DISC_BUF_SIZE GKI_MAX_BUF_SIZE
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* The type of devices supported by BTA HH and corresponding application ID */
|
||||
tBTA_HH_SPT_TOD p_devt_list[BTA_HH_MAX_DEVT_SPT] = {
|
||||
{BTA_HH_DEVT_MIC, BTA_HH_APP_ID_MI},
|
||||
{BTA_HH_DEVT_KBD, BTA_HH_APP_ID_KB},
|
||||
{BTA_HH_DEVT_KBD | BTA_HH_DEVT_MIC, BTA_HH_APP_ID_KB},
|
||||
{BTA_HH_DEVT_RMC, BTA_HH_APP_ID_RMC},
|
||||
{BTA_HH_DEVT_RMC | BTA_HH_DEVT_KBD, BTA_HH_APP_ID_RMC},
|
||||
{BTA_HH_DEVT_MIC | BTA_HH_DEVT_DGT, BTA_HH_APP_ID_MI},
|
||||
{BTA_HH_DEVT_JOS, BTA_HH_APP_ID_JOY},
|
||||
{BTA_HH_DEVT_GPD, BTA_HH_APP_ID_GPAD},
|
||||
{BTA_HH_DEVT_UNKNOWN, BTA_HH_APP_ID_3DSG}
|
||||
};
|
||||
|
||||
|
||||
const tBTA_HH_CFG bta_hh_cfg = {
|
||||
BTA_HH_MAX_DEVT_SPT, /* number of supported type of devices */
|
||||
p_devt_list, /* ToD & AppID list */
|
||||
BTA_HH_DISC_BUF_SIZE /* HH SDP discovery database size */
|
||||
};
|
||||
|
||||
|
||||
tBTA_HH_CFG *p_bta_hh_cfg = (tBTA_HH_CFG *) &bta_hh_cfg;
|
||||
399
components/bt/bluedroid/bta/hh/bta_hh_int.h
Normal file
399
components/bt/bluedroid/bta/hh/bta_hh_int.h
Normal file
@@ -0,0 +1,399 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains BTA HID Host internal definitions
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef BTA_HH_INT_H
|
||||
#define BTA_HH_INT_H
|
||||
|
||||
#include "bta_sys.h"
|
||||
#include "utl.h"
|
||||
#include "bta_hh_api.h"
|
||||
|
||||
//#if BTA_HH_LE_INCLUDED == TRUE
|
||||
#include "bta_gatt_api.h"
|
||||
//#endif
|
||||
|
||||
/* can be moved to bta_api.h */
|
||||
#define BTA_HH_MAX_RPT_CHARS 8
|
||||
|
||||
#if (BTA_GATT_INCLUDED == FALSE || BLE_INCLUDED == FALSE)
|
||||
#undef BTA_HH_LE_INCLUDED
|
||||
#define BTA_HH_LE_INCLUDED FALSE
|
||||
#endif
|
||||
|
||||
/* state machine events, these events are handled by the state machine */
|
||||
enum {
|
||||
BTA_HH_API_OPEN_EVT = BTA_SYS_EVT_START(BTA_ID_HH),
|
||||
BTA_HH_API_CLOSE_EVT,
|
||||
BTA_HH_INT_OPEN_EVT,
|
||||
BTA_HH_INT_CLOSE_EVT,
|
||||
BTA_HH_INT_DATA_EVT,
|
||||
BTA_HH_INT_CTRL_DATA,
|
||||
BTA_HH_INT_HANDSK_EVT,
|
||||
BTA_HH_SDP_CMPL_EVT,
|
||||
BTA_HH_API_WRITE_DEV_EVT,
|
||||
BTA_HH_API_GET_DSCP_EVT,
|
||||
BTA_HH_API_MAINT_DEV_EVT,
|
||||
BTA_HH_OPEN_CMPL_EVT,
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
BTA_HH_GATT_CLOSE_EVT,
|
||||
BTA_HH_GATT_OPEN_EVT,
|
||||
BTA_HH_START_ENC_EVT,
|
||||
BTA_HH_ENC_CMPL_EVT,
|
||||
BTA_HH_GATT_READ_CHAR_CMPL_EVT,
|
||||
BTA_HH_GATT_WRITE_CHAR_CMPL_EVT,
|
||||
BTA_HH_GATT_READ_DESCR_CMPL_EVT,
|
||||
BTA_HH_GATT_WRITE_DESCR_CMPL_EVT,
|
||||
BTA_HH_API_SCPP_UPDATE_EVT,
|
||||
BTA_HH_GATT_ENC_CMPL_EVT,
|
||||
#endif
|
||||
|
||||
/* not handled by execute state machine */
|
||||
BTA_HH_API_ENABLE_EVT,
|
||||
BTA_HH_API_DISABLE_EVT,
|
||||
BTA_HH_DISC_CMPL_EVT
|
||||
};
|
||||
typedef UINT16 tBTA_HH_INT_EVT; /* HID host internal events */
|
||||
|
||||
#define BTA_HH_INVALID_EVT (BTA_HH_DISC_CMPL_EVT + 1)
|
||||
|
||||
/* event used to map between BTE event and BTA event */
|
||||
#define BTA_HH_FST_TRANS_CB_EVT BTA_HH_GET_RPT_EVT
|
||||
#define BTA_HH_FST_BTE_TRANS_EVT HID_TRANS_GET_REPORT
|
||||
|
||||
/* sub event code used for device maintainence API call */
|
||||
#define BTA_HH_ADD_DEV 0
|
||||
#define BTA_HH_REMOVE_DEV 1
|
||||
|
||||
/* state machine states */
|
||||
enum {
|
||||
BTA_HH_NULL_ST,
|
||||
BTA_HH_IDLE_ST,
|
||||
BTA_HH_W4_CONN_ST,
|
||||
BTA_HH_CONN_ST
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
, BTA_HH_W4_SEC
|
||||
#endif
|
||||
, BTA_HH_INVALID_ST /* Used to check invalid states before executing SM function */
|
||||
|
||||
};
|
||||
typedef UINT8 tBTA_HH_STATE;
|
||||
|
||||
/* data structure used to send a command/data to HID device */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT8 t_type;
|
||||
UINT8 param;
|
||||
UINT8 rpt_id;
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
UINT8 srvc_id;
|
||||
#endif
|
||||
UINT16 data;
|
||||
BT_HDR *p_data;
|
||||
} tBTA_HH_CMD_DATA;
|
||||
|
||||
/* data type for BTA_HH_API_ENABLE_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT8 sec_mask;
|
||||
UINT8 service_name[BTA_SERVICE_NAME_LEN + 1];
|
||||
tBTA_HH_CBACK *p_cback;
|
||||
} tBTA_HH_API_ENABLE;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR bd_addr;
|
||||
UINT8 sec_mask;
|
||||
tBTA_HH_PROTO_MODE mode;
|
||||
} tBTA_HH_API_CONN;
|
||||
|
||||
/* internal event data from BTE HID callback */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR addr;
|
||||
UINT32 data;
|
||||
BT_HDR *p_data;
|
||||
} tBTA_HH_CBACK_DATA;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR bda;
|
||||
UINT16 attr_mask;
|
||||
UINT16 sub_event;
|
||||
UINT8 sub_class;
|
||||
UINT8 app_id;
|
||||
tBTA_HH_DEV_DSCP_INFO dscp_info;
|
||||
} tBTA_HH_MAINT_DEV;
|
||||
|
||||
#if BTA_HH_LE_INCLUDED == TRUE
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT16 conn_id;
|
||||
tBTA_GATT_REASON reason; /* disconnect reason code, not useful when connect event is reported */
|
||||
|
||||
} tBTA_HH_LE_CLOSE;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT16 scan_int;
|
||||
UINT16 scan_win;
|
||||
} tBTA_HH_SCPP_UPDATE;
|
||||
#endif
|
||||
/* union of all event data types */
|
||||
typedef union {
|
||||
BT_HDR hdr;
|
||||
tBTA_HH_API_ENABLE api_enable;
|
||||
tBTA_HH_API_CONN api_conn;
|
||||
tBTA_HH_CMD_DATA api_sndcmd;
|
||||
tBTA_HH_CBACK_DATA hid_cback;
|
||||
tBTA_HH_STATUS status;
|
||||
tBTA_HH_MAINT_DEV api_maintdev;
|
||||
#if BTA_HH_LE_INCLUDED == TRUE
|
||||
tBTA_HH_LE_CLOSE le_close;
|
||||
tBTA_GATTC_OPEN le_open;
|
||||
tBTA_HH_SCPP_UPDATE le_scpp_update;
|
||||
tBTA_GATTC_ENC_CMPL_CB le_enc_cmpl;
|
||||
#endif
|
||||
} tBTA_HH_DATA;
|
||||
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
typedef struct {
|
||||
UINT8 index;
|
||||
BOOLEAN in_use;
|
||||
UINT8 inst_id; /* share service instance ID and report instance ID, as
|
||||
hi 4 for service instance ID, low 4 as charatceristic instance ID */
|
||||
tBTA_HH_RPT_TYPE rpt_type;
|
||||
UINT16 uuid;
|
||||
UINT8 prop;
|
||||
UINT8 rpt_id;
|
||||
BOOLEAN client_cfg_exist;
|
||||
UINT16 client_cfg_value;
|
||||
} tBTA_HH_LE_RPT;
|
||||
|
||||
#ifndef BTA_HH_LE_RPT_MAX
|
||||
#define BTA_HH_LE_RPT_MAX 20
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
BOOLEAN in_use;
|
||||
tBTA_HH_LE_RPT report[BTA_HH_LE_RPT_MAX];
|
||||
|
||||
#define BTA_HH_LE_PROTO_MODE_BIT 0x01
|
||||
#define BTA_HH_LE_CP_BIT 0x02
|
||||
UINT8 option_char; /* control point char exisit or not */
|
||||
|
||||
BOOLEAN expl_incl_srvc;
|
||||
UINT8 incl_srvc_inst; /* assuming only one included service : battery service */
|
||||
UINT8 cur_expl_char_idx; /* currently discovering service index */
|
||||
UINT8 *rpt_map;
|
||||
UINT16 ext_rpt_ref;
|
||||
tBTA_HH_DEV_DESCR descriptor;
|
||||
|
||||
} tBTA_HH_LE_HID_SRVC;
|
||||
|
||||
#ifndef BTA_HH_LE_HID_SRVC_MAX
|
||||
#define BTA_HH_LE_HID_SRVC_MAX 1
|
||||
#endif
|
||||
|
||||
/* convert a HID handle to the LE CB index */
|
||||
#define BTA_HH_GET_LE_CB_IDX(x) (((x) >> 4) - 1)
|
||||
/* convert a GATT connection ID to HID device handle, it is the hi 4 bits of a UINT8 */
|
||||
#define BTA_HH_GET_LE_DEV_HDL(x) (UINT8)(((x) + 1) << 4)
|
||||
/* check to see if th edevice handle is a LE device handle */
|
||||
#define BTA_HH_IS_LE_DEV_HDL(x) ((x) & 0xf0)
|
||||
#define BTA_HH_IS_LE_DEV_HDL_VALID(x) (((x)>>4) <= BTA_HH_LE_MAX_KNOWN)
|
||||
#endif
|
||||
|
||||
/* device control block */
|
||||
typedef struct {
|
||||
tBTA_HH_DEV_DSCP_INFO dscp_info; /* report descriptor and DI information */
|
||||
BD_ADDR addr; /* BD-Addr of the HID device */
|
||||
UINT16 attr_mask; /* attribute mask */
|
||||
UINT16 w4_evt; /* W4_handshake event name */
|
||||
UINT8 index; /* index number referenced to handle index */
|
||||
UINT8 sub_class; /* Cod sub class */
|
||||
UINT8 sec_mask; /* security mask */
|
||||
UINT8 app_id; /* application ID for this connection */
|
||||
UINT8 hid_handle; /* device handle : low 4 bits for regular HID: HID_HOST_MAX_DEVICES can not exceed 15;
|
||||
high 4 bits for LE HID: GATT_MAX_PHY_CHANNEL can not exceed 15 */
|
||||
BOOLEAN vp; /* virtually unplug flag */
|
||||
BOOLEAN in_use; /* control block currently in use */
|
||||
BOOLEAN incoming_conn; /* is incoming connection? */
|
||||
UINT8 incoming_hid_handle; /* temporary handle for incoming connection? */
|
||||
BOOLEAN opened; /* TRUE if device successfully opened HID connection */
|
||||
tBTA_HH_PROTO_MODE mode; /* protocol mode */
|
||||
tBTA_HH_STATE state; /* CB state */
|
||||
|
||||
#if (BTA_HH_LE_INCLUDED == TRUE)
|
||||
#define BTA_HH_LE_DISC_NONE 0x00
|
||||
#define BTA_HH_LE_DISC_HIDS 0x01
|
||||
#define BTA_HH_LE_DISC_DIS 0x02
|
||||
#define BTA_HH_LE_DISC_SCPS 0x04
|
||||
|
||||
UINT8 disc_active;
|
||||
tBTA_HH_STATUS status;
|
||||
tBTA_GATT_REASON reason;
|
||||
BOOLEAN is_le_device;
|
||||
tBTA_HH_LE_HID_SRVC hid_srvc[BTA_HH_LE_HID_SRVC_MAX];
|
||||
UINT16 conn_id;
|
||||
BOOLEAN in_bg_conn;
|
||||
UINT8 total_srvc;
|
||||
UINT8 clt_cfg_idx;
|
||||
UINT8 cur_srvc_index; /* currently discovering service index */
|
||||
BOOLEAN scps_supported;
|
||||
|
||||
#define BTA_HH_LE_SCPS_NOTIFY_NONE 0
|
||||
#define BTA_HH_LE_SCPS_NOTIFY_SPT 0x01
|
||||
#define BTA_HH_LE_SCPS_NOTIFY_ENB 0x02
|
||||
UINT8 scps_notify; /* scan refresh supported/notification enabled */
|
||||
#endif
|
||||
|
||||
BOOLEAN security_pending;
|
||||
} tBTA_HH_DEV_CB;
|
||||
|
||||
/* key board parsing control block */
|
||||
typedef struct {
|
||||
BOOLEAN mod_key[4]; /* ctrl, shift(upper), Alt, GUI */
|
||||
BOOLEAN num_lock;
|
||||
BOOLEAN caps_lock;
|
||||
UINT8 last_report[BTA_HH_MAX_RPT_CHARS];
|
||||
} tBTA_HH_KB_CB;
|
||||
|
||||
/******************************************************************************
|
||||
** Main Control Block
|
||||
*******************************************************************************/
|
||||
typedef struct {
|
||||
tBTA_HH_KB_CB kb_cb; /* key board control block,
|
||||
suppose BTA will connect
|
||||
to only one keyboard at
|
||||
the same time */
|
||||
tBTA_HH_DEV_CB kdev[BTA_HH_MAX_DEVICE]; /* device control block */
|
||||
tBTA_HH_DEV_CB *p_cur; /* current device control
|
||||
block idx, used in sdp */
|
||||
UINT8 cb_index[BTA_HH_MAX_KNOWN]; /* maintain a CB index
|
||||
map to dev handle */
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
UINT8 le_cb_index[BTA_HH_MAX_DEVICE]; /* maintain a CB index map to LE dev handle */
|
||||
tBTA_GATTC_IF gatt_if;
|
||||
#endif
|
||||
tBTA_HH_CBACK *p_cback; /* Application callbacks */
|
||||
tSDP_DISCOVERY_DB *p_disc_db;
|
||||
UINT8 trace_level; /* tracing level */
|
||||
UINT8 cnt_num; /* connected device number */
|
||||
BOOLEAN w4_disable; /* w4 disable flag */
|
||||
}
|
||||
tBTA_HH_CB;
|
||||
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
extern tBTA_HH_CB bta_hh_cb;
|
||||
#else
|
||||
extern tBTA_HH_CB *bta_hh_cb_ptr;
|
||||
#define bta_hh_cb (*bta_hh_cb_ptr)
|
||||
#endif
|
||||
|
||||
/* from bta_hh_cfg.c */
|
||||
extern tBTA_HH_CFG *p_bta_hh_cfg;
|
||||
|
||||
/*****************************************************************************
|
||||
** Function prototypes
|
||||
*****************************************************************************/
|
||||
extern BOOLEAN bta_hh_hdl_event(BT_HDR *p_msg);
|
||||
extern void bta_hh_sm_execute(tBTA_HH_DEV_CB *p_cb, UINT16 event,
|
||||
tBTA_HH_DATA *p_data);
|
||||
|
||||
/* action functions */
|
||||
extern void bta_hh_api_disc_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_open_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_close_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_data_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_ctrl_dat_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_start_sdp(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_sdp_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_write_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_get_dscp_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_handsk_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_maint_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_open_cmpl_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_open_failure(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
|
||||
/* utility functions */
|
||||
extern UINT8 bta_hh_find_cb(BD_ADDR bda);
|
||||
extern void bta_hh_parse_keybd_rpt(tBTA_HH_BOOT_RPT *p_kb_data,
|
||||
UINT8 *p_report, UINT16 report_len);
|
||||
extern void bta_hh_parse_mice_rpt(tBTA_HH_BOOT_RPT *p_kb_data,
|
||||
UINT8 *p_report, UINT16 report_len);
|
||||
extern BOOLEAN bta_hh_tod_spt(tBTA_HH_DEV_CB *p_cb, UINT8 sub_class);
|
||||
extern void bta_hh_clean_up_kdev(tBTA_HH_DEV_CB *p_cb);
|
||||
|
||||
extern void bta_hh_add_device_to_list(tBTA_HH_DEV_CB *p_cb, UINT8 handle,
|
||||
UINT16 attr_mask,
|
||||
tHID_DEV_DSCP_INFO *p_dscp_info,
|
||||
UINT8 sub_class, UINT16 max_latency, UINT16 min_tout, UINT8 app_id);
|
||||
extern void bta_hh_update_di_info(tBTA_HH_DEV_CB *p_cb, UINT16 vendor_id, UINT16 product_id,
|
||||
UINT16 version, UINT8 flag);
|
||||
extern void bta_hh_cleanup_disable(tBTA_HH_STATUS status);
|
||||
|
||||
extern UINT8 bta_hh_dev_handle_to_cb_idx(UINT8 dev_handle);
|
||||
|
||||
/* action functions used outside state machine */
|
||||
extern void bta_hh_api_enable(tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_api_disable(void);
|
||||
extern void bta_hh_disc_cmpl(void);
|
||||
|
||||
extern tBTA_HH_STATUS bta_hh_read_ssr_param(BD_ADDR bd_addr, UINT16 *p_max_ssr_lat, UINT16 *p_min_ssr_tout);
|
||||
|
||||
/* functions for LE HID */
|
||||
extern void bta_hh_le_enable(void);
|
||||
extern BOOLEAN bta_hh_le_is_hh_gatt_if(tBTA_GATTC_IF client_if);
|
||||
extern void bta_hh_le_deregister(void);
|
||||
extern BOOLEAN bta_hh_is_le_device(tBTA_HH_DEV_CB *p_cb, BD_ADDR remote_bda);
|
||||
extern void bta_hh_le_open_conn(tBTA_HH_DEV_CB *p_cb, BD_ADDR remote_bda);
|
||||
extern void bta_hh_le_api_disc_act(tBTA_HH_DEV_CB *p_cb);
|
||||
extern void bta_hh_le_get_dscp_act(tBTA_HH_DEV_CB *p_cb);
|
||||
extern void bta_hh_le_write_dev_act(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern UINT8 bta_hh_le_add_device(tBTA_HH_DEV_CB *p_cb, tBTA_HH_MAINT_DEV *p_dev_info);
|
||||
extern void bta_hh_le_remove_dev_bg_conn(tBTA_HH_DEV_CB *p_cb);
|
||||
extern void bta_hh_le_open_fail(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_gatt_open(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_gatt_close(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_start_security(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_start_srvc_discovery(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_w4_le_read_char_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_le_read_char_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_w4_le_read_descr_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_le_read_descr_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_w4_le_write_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_le_write_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_le_write_char_descr_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_start_security(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_security_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_le_update_scpp(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
extern void bta_hh_le_notify_enc_cmpl(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
extern void bta_hh_ci_load_rpt (tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_buf);
|
||||
|
||||
#if BTA_HH_DEBUG
|
||||
extern void bta_hh_trace_dev_db(void);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
3024
components/bt/bluedroid/bta/hh/bta_hh_le.c
Normal file
3024
components/bt/bluedroid/bta/hh/bta_hh_le.c
Normal file
File diff suppressed because it is too large
Load Diff
560
components/bt/bluedroid/bta/hh/bta_hh_main.c
Normal file
560
components/bt/bluedroid/bta/hh/bta_hh_main.c
Normal file
@@ -0,0 +1,560 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This file contains the HID host main functions and state machine.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bt_target.h"
|
||||
|
||||
#if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "bta_hh_api.h"
|
||||
#include "bta_hh_int.h"
|
||||
#include "gki.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and types
|
||||
*****************************************************************************/
|
||||
|
||||
/* state machine action enumeration list */
|
||||
enum {
|
||||
BTA_HH_API_DISC_ACT, /* HID host process API close action */
|
||||
BTA_HH_OPEN_ACT, /* HID host process BTA_HH_EVT_OPEN */
|
||||
BTA_HH_CLOSE_ACT, /* HID host process BTA_HH_EVT_CLOSE */
|
||||
BTA_HH_DATA_ACT, /* HID host receive data report */
|
||||
BTA_HH_CTRL_DAT_ACT,
|
||||
BTA_HH_HANDSK_ACT,
|
||||
BTA_HH_START_SDP, /* HID host inquery */
|
||||
BTA_HH_SDP_CMPL,
|
||||
BTA_HH_WRITE_DEV_ACT,
|
||||
BTA_HH_GET_DSCP_ACT,
|
||||
BTA_HH_MAINT_DEV_ACT,
|
||||
BTA_HH_OPEN_CMPL_ACT,
|
||||
BTA_HH_OPEN_FAILURE,
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
BTA_HH_GATT_CLOSE,
|
||||
BTA_HH_LE_OPEN_FAIL,
|
||||
BTA_HH_GATT_OPEN,
|
||||
BTA_HH_W4_LE_READ_CHAR,
|
||||
BTA_HH_LE_READ_CHAR,
|
||||
BTA_HH_W4_LE_READ_DESCR,
|
||||
BTA_HH_LE_READ_DESCR,
|
||||
BTA_HH_W4_LE_WRITE,
|
||||
BTA_HH_LE_WRITE,
|
||||
BTA_HH_WRITE_DESCR,
|
||||
BTA_HH_START_SEC,
|
||||
BTA_HH_SEC_CMPL,
|
||||
BTA_HH_LE_UPDATE_SCPP,
|
||||
BTA_HH_GATT_ENC_CMPL,
|
||||
#endif
|
||||
BTA_HH_NUM_ACTIONS
|
||||
};
|
||||
|
||||
#define BTA_HH_IGNORE BTA_HH_NUM_ACTIONS
|
||||
|
||||
/* type for action functions */
|
||||
typedef void (*tBTA_HH_ACTION)(tBTA_HH_DEV_CB *p_cb, tBTA_HH_DATA *p_data);
|
||||
|
||||
/* action functions */
|
||||
const tBTA_HH_ACTION bta_hh_action[] = {
|
||||
bta_hh_api_disc_act,
|
||||
bta_hh_open_act,
|
||||
bta_hh_close_act,
|
||||
bta_hh_data_act,
|
||||
bta_hh_ctrl_dat_act,
|
||||
bta_hh_handsk_act,
|
||||
bta_hh_start_sdp,
|
||||
bta_hh_sdp_cmpl,
|
||||
bta_hh_write_dev_act,
|
||||
bta_hh_get_dscp_act,
|
||||
bta_hh_maint_dev_act,
|
||||
bta_hh_open_cmpl_act,
|
||||
bta_hh_open_failure
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
, bta_hh_gatt_close
|
||||
, bta_hh_le_open_fail
|
||||
, bta_hh_gatt_open
|
||||
, bta_hh_w4_le_read_char_cmpl
|
||||
, bta_hh_le_read_char_cmpl
|
||||
, bta_hh_w4_le_read_descr_cmpl
|
||||
, bta_hh_le_read_descr_cmpl
|
||||
, bta_hh_w4_le_write_cmpl
|
||||
, bta_hh_le_write_cmpl
|
||||
, bta_hh_le_write_char_descr_cmpl
|
||||
, bta_hh_start_security
|
||||
, bta_hh_security_cmpl
|
||||
, bta_hh_le_update_scpp
|
||||
, bta_hh_le_notify_enc_cmpl
|
||||
#endif
|
||||
};
|
||||
|
||||
/* state table information */
|
||||
#define BTA_HH_ACTION 0 /* position of action */
|
||||
#define BTA_HH_NEXT_STATE 1 /* position of next state */
|
||||
#define BTA_HH_NUM_COLS 2 /* number of columns */
|
||||
|
||||
/* state table for idle state */
|
||||
const UINT8 bta_hh_st_idle[][BTA_HH_NUM_COLS] = {
|
||||
/* Event Action Next state */
|
||||
/* BTA_HH_API_OPEN_EVT */ {BTA_HH_START_SDP, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_API_CLOSE_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_OPEN_EVT */ {BTA_HH_OPEN_ACT, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_INT_CLOSE_EVT */ {BTA_HH_CLOSE_ACT, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_DATA_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_CTRL_DATA */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_HANDSK_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_SDP_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_API_WRITE_DEV_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_API_GET_DSCP_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_API_MAINT_DEV_EVT */ {BTA_HH_MAINT_DEV_ACT, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_OPEN_CMPL_EVT */ {BTA_HH_OPEN_CMPL_ACT, BTA_HH_CONN_ST }
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
/* BTA_HH_GATT_CLOSE_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* BTA_HH_GATT_OPEN_EVT */ , {BTA_HH_GATT_OPEN, BTA_HH_W4_CONN_ST }
|
||||
/* BTA_HH_START_ENC_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* BTA_HH_ENC_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* READ_CHAR_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* BTA_HH_GATT_WRITE_CMPL_EVT*/ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* READ_DESCR_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* WRITE_DESCR_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* SCPP_UPDATE_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
/* BTA_HH_GATT_ENC_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_IDLE_ST }
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
const UINT8 bta_hh_st_w4_conn[][BTA_HH_NUM_COLS] = {
|
||||
/* Event Action Next state */
|
||||
/* BTA_HH_API_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_API_CLOSE_EVT */ {BTA_HH_IGNORE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_OPEN_EVT */ {BTA_HH_OPEN_ACT, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_INT_CLOSE_EVT */ {BTA_HH_OPEN_FAILURE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_DATA_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_INT_CTRL_DATA */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_INT_HANDSK_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_SDP_CMPL_EVT */ {BTA_HH_SDP_CMPL, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_API_WRITE_DEV_EVT */ {BTA_HH_WRITE_DEV_ACT, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_API_GET_DSCP_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST },
|
||||
/* BTA_HH_API_MAINT_DEV_EVT */ {BTA_HH_MAINT_DEV_ACT, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_OPEN_CMPL_EVT */ {BTA_HH_OPEN_CMPL_ACT, BTA_HH_CONN_ST }
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
/* BTA_HH_GATT_CLOSE_EVT */ , {BTA_HH_LE_OPEN_FAIL, BTA_HH_IDLE_ST }
|
||||
/* BTA_HH_GATT_OPEN_EVT */ , {BTA_HH_GATT_OPEN, BTA_HH_W4_CONN_ST }
|
||||
/* BTA_HH_START_ENC_EVT */ , {BTA_HH_START_SEC, BTA_HH_W4_SEC }
|
||||
/* BTA_HH_ENC_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST }
|
||||
/* READ_CHAR_CMPL_EVT */ , {BTA_HH_W4_LE_READ_CHAR, BTA_HH_W4_CONN_ST }
|
||||
/* BTA_HH_GATT_WRITE_CMPL_EVT*/ , {BTA_HH_W4_LE_WRITE, BTA_HH_W4_CONN_ST }
|
||||
/* READ_DESCR_CMPL_EVT */ , {BTA_HH_W4_LE_READ_DESCR, BTA_HH_W4_CONN_ST }
|
||||
/* WRITE_DESCR_CMPL_EVT */ , {BTA_HH_WRITE_DESCR, BTA_HH_W4_CONN_ST }
|
||||
/* SCPP_UPDATE_EVT */ , {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST }
|
||||
/* BTA_HH_GATT_ENC_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_W4_CONN_ST }
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
const UINT8 bta_hh_st_connected[][BTA_HH_NUM_COLS] = {
|
||||
/* Event Action Next state */
|
||||
/* BTA_HH_API_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_API_CLOSE_EVT */ {BTA_HH_API_DISC_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_INT_OPEN_EVT */ {BTA_HH_OPEN_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_INT_CLOSE_EVT */ {BTA_HH_CLOSE_ACT, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_DATA_EVT */ {BTA_HH_DATA_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_INT_CTRL_DATA */ {BTA_HH_CTRL_DAT_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_INT_HANDSK_EVT */ {BTA_HH_HANDSK_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_SDP_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_API_WRITE_DEV_EVT */ {BTA_HH_WRITE_DEV_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_API_GET_DSCP_EVT */ {BTA_HH_GET_DSCP_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_API_MAINT_DEV_EVT */ {BTA_HH_MAINT_DEV_ACT, BTA_HH_CONN_ST },
|
||||
/* BTA_HH_OPEN_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_CONN_ST }
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
/* BTA_HH_GATT_CLOSE_EVT */ , {BTA_HH_GATT_CLOSE, BTA_HH_IDLE_ST }
|
||||
/* BTA_HH_GATT_OPEN_EVT */ , {BTA_HH_IGNORE, BTA_HH_CONN_ST }
|
||||
/* BTA_HH_START_ENC_EVT */ , {BTA_HH_IGNORE, BTA_HH_CONN_ST }
|
||||
/* BTA_HH_ENC_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_CONN_ST }
|
||||
/* READ_CHAR_CMPL_EVT */ , {BTA_HH_LE_READ_CHAR, BTA_HH_CONN_ST }
|
||||
/* WRITE_CHAR_CMPL_EVT*/ , {BTA_HH_LE_WRITE, BTA_HH_CONN_ST }
|
||||
/* READ_DESCR_CMPL_EVT */ , {BTA_HH_LE_READ_DESCR, BTA_HH_CONN_ST } /* do not currently read any descr when connection up */
|
||||
/* WRITE_DESCR_CMPL_EVT */ , {BTA_HH_WRITE_DESCR, BTA_HH_CONN_ST } /* do not currently write any descr when connection up */
|
||||
/* SCPP_UPDATE_EVT */ , {BTA_HH_LE_UPDATE_SCPP, BTA_HH_CONN_ST }
|
||||
/* BTA_HH_GATT_ENC_CMPL_EVT */ , {BTA_HH_IGNORE, BTA_HH_CONN_ST }
|
||||
#endif
|
||||
};
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
const UINT8 bta_hh_st_w4_sec[][BTA_HH_NUM_COLS] = {
|
||||
/* Event Action Next state */
|
||||
/* BTA_HH_API_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_API_CLOSE_EVT */ {BTA_HH_API_DISC_ACT, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_INT_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_INT_CLOSE_EVT */ {BTA_HH_OPEN_FAILURE, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_INT_DATA_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_INT_CTRL_DATA */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_INT_HANDSK_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_SDP_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_API_WRITE_DEV_EVT */ {BTA_HH_IGNORE , BTA_HH_W4_SEC },
|
||||
/* BTA_HH_API_GET_DSCP_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_API_MAINT_DEV_EVT */ {BTA_HH_MAINT_DEV_ACT, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_OPEN_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_GATT_CLOSE_EVT */ {BTA_HH_LE_OPEN_FAIL, BTA_HH_IDLE_ST },
|
||||
/* BTA_HH_GATT_OPEN_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_START_ENC_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_ENC_CMPL_EVT */ {BTA_HH_SEC_CMPL, BTA_HH_W4_CONN_ST },
|
||||
/* READ_CHAR_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* BTA_HH_GATT_WRITE_CMPL_EVT*/ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* READ_DESCR_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC },
|
||||
/* WRITE_DESCR_CMPL_EVT */ {BTA_HH_IGNORE, BTA_HH_W4_SEC }
|
||||
/* SCPP_UPDATE_EVT */ , {BTA_HH_IGNORE, BTA_HH_W4_SEC }
|
||||
/* BTA_HH_GATT_ENC_CMPL_EVT */ , {BTA_HH_GATT_ENC_CMPL, BTA_HH_W4_SEC }
|
||||
};
|
||||
#endif
|
||||
|
||||
/* type for state table */
|
||||
typedef const UINT8 (*tBTA_HH_ST_TBL)[BTA_HH_NUM_COLS];
|
||||
|
||||
/* state table */
|
||||
const tBTA_HH_ST_TBL bta_hh_st_tbl[] = {
|
||||
bta_hh_st_idle,
|
||||
bta_hh_st_w4_conn,
|
||||
bta_hh_st_connected
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
, bta_hh_st_w4_sec
|
||||
#endif
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
** Global data
|
||||
*****************************************************************************/
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
tBTA_HH_CB bta_hh_cb;
|
||||
#endif
|
||||
/*****************************************************************************
|
||||
** Static functions
|
||||
*****************************************************************************/
|
||||
#if BTA_HH_DEBUG == TRUE
|
||||
static char *bta_hh_evt_code(tBTA_HH_INT_EVT evt_code);
|
||||
static char *bta_hh_state_code(tBTA_HH_STATE state_code);
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_sm_execute
|
||||
**
|
||||
** Description State machine event handling function for HID Host
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_sm_execute(tBTA_HH_DEV_CB *p_cb, UINT16 event, tBTA_HH_DATA *p_data)
|
||||
{
|
||||
tBTA_HH_ST_TBL state_table;
|
||||
UINT8 action;
|
||||
tBTA_HH cback_data;
|
||||
tBTA_HH_EVT cback_event = 0;
|
||||
#if BTA_HH_DEBUG == TRUE
|
||||
tBTA_HH_STATE in_state ;
|
||||
UINT16 debug_event = event;
|
||||
#endif
|
||||
|
||||
memset(&cback_data, 0, sizeof(tBTA_HH));
|
||||
|
||||
/* handle exception, no valid control block was found */
|
||||
if (!p_cb) {
|
||||
/* BTA HH enabled already? otherwise ignore the event although it's bad*/
|
||||
if (bta_hh_cb.p_cback != NULL) {
|
||||
switch (event) {
|
||||
/* no control block available for new connection */
|
||||
case BTA_HH_API_OPEN_EVT:
|
||||
cback_event = BTA_HH_OPEN_EVT;
|
||||
/* build cback data */
|
||||
bdcpy(cback_data.conn.bda, ((tBTA_HH_API_CONN *)p_data)->bd_addr);
|
||||
cback_data.conn.status = BTA_HH_ERR_DB_FULL;
|
||||
cback_data.conn.handle = BTA_HH_INVALID_HANDLE;
|
||||
break;
|
||||
/* DB full, BTA_HhAddDev */
|
||||
case BTA_HH_API_MAINT_DEV_EVT:
|
||||
cback_event = p_data->api_maintdev.sub_event;
|
||||
|
||||
if (p_data->api_maintdev.sub_event == BTA_HH_ADD_DEV_EVT) {
|
||||
bdcpy(cback_data.dev_info.bda, p_data->api_maintdev.bda);
|
||||
cback_data.dev_info.status = BTA_HH_ERR_DB_FULL;
|
||||
cback_data.dev_info.handle = BTA_HH_INVALID_HANDLE;
|
||||
} else {
|
||||
cback_data.dev_info.status = BTA_HH_ERR_HDL;
|
||||
cback_data.dev_info.handle = (UINT8)p_data->api_maintdev.hdr.layer_specific;
|
||||
}
|
||||
break;
|
||||
case BTA_HH_API_WRITE_DEV_EVT:
|
||||
cback_event = (p_data->api_sndcmd.t_type - BTA_HH_FST_BTE_TRANS_EVT) +
|
||||
BTA_HH_FST_TRANS_CB_EVT;
|
||||
if (p_data->api_sndcmd.p_data != NULL) {
|
||||
GKI_freebuf(p_data->api_sndcmd.p_data);
|
||||
}
|
||||
if (p_data->api_sndcmd.t_type == HID_TRANS_SET_PROTOCOL ||
|
||||
p_data->api_sndcmd.t_type == HID_TRANS_SET_REPORT ||
|
||||
p_data->api_sndcmd.t_type == HID_TRANS_SET_IDLE) {
|
||||
cback_data.dev_status.status = BTA_HH_ERR_HDL;
|
||||
cback_data.dev_status.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
|
||||
} else if (p_data->api_sndcmd.t_type != HID_TRANS_DATA &&
|
||||
p_data->api_sndcmd.t_type != HID_TRANS_CONTROL) {
|
||||
cback_data.hs_data.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
|
||||
cback_data.hs_data.status = BTA_HH_ERR_HDL;
|
||||
/* hs_data.rsp_data will be all zero, which is not valid value */
|
||||
} else if (p_data->api_sndcmd.t_type == HID_TRANS_CONTROL &&
|
||||
p_data->api_sndcmd.param == BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG) {
|
||||
cback_data.status = BTA_HH_ERR_HDL;
|
||||
cback_event = BTA_HH_VC_UNPLUG_EVT;
|
||||
} else {
|
||||
cback_event = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case BTA_HH_API_CLOSE_EVT:
|
||||
cback_event = BTA_HH_CLOSE_EVT;
|
||||
|
||||
cback_data.dev_status.status = BTA_HH_ERR_HDL;
|
||||
cback_data.dev_status.handle = (UINT8)p_data->api_sndcmd.hdr.layer_specific;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* invalid handle, call bad API event */
|
||||
APPL_TRACE_ERROR("wrong device handle: [%d]", p_data->hdr.layer_specific);
|
||||
/* Free the callback buffer now */
|
||||
if (p_data != NULL && p_data->hid_cback.p_data != NULL) {
|
||||
GKI_freebuf(p_data->hid_cback.p_data);
|
||||
p_data->hid_cback.p_data = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (cback_event) {
|
||||
(* bta_hh_cb.p_cback)(cback_event, &cback_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* corresponding CB is found, go to state machine */
|
||||
else {
|
||||
#if BTA_HH_DEBUG == TRUE
|
||||
in_state = p_cb->state;
|
||||
APPL_TRACE_EVENT("bta_hh_sm_execute: State 0x%02x [%s], Event [%s]",
|
||||
in_state, bta_hh_state_code(in_state),
|
||||
bta_hh_evt_code(debug_event));
|
||||
#endif
|
||||
|
||||
if ((p_cb->state == BTA_HH_NULL_ST) || (p_cb->state >= BTA_HH_INVALID_ST)) {
|
||||
APPL_TRACE_ERROR("bta_hh_sm_execute: Invalid state State = 0x%x, Event = %d",
|
||||
p_cb->state, event);
|
||||
return;
|
||||
}
|
||||
state_table = bta_hh_st_tbl[p_cb->state - 1];
|
||||
|
||||
event &= 0xff;
|
||||
|
||||
p_cb->state = state_table[event][BTA_HH_NEXT_STATE] ;
|
||||
|
||||
if ((action = state_table[event][BTA_HH_ACTION]) != BTA_HH_IGNORE) {
|
||||
(*bta_hh_action[action])(p_cb, p_data);
|
||||
}
|
||||
|
||||
#if BTA_HH_DEBUG == TRUE
|
||||
if (in_state != p_cb->state) {
|
||||
APPL_TRACE_DEBUG("HH State Change: [%s] -> [%s] after Event [%s]",
|
||||
bta_hh_state_code(in_state),
|
||||
bta_hh_state_code(p_cb->state),
|
||||
bta_hh_evt_code(debug_event));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_hdl_event
|
||||
**
|
||||
** Description HID host main event handling function.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_hh_hdl_event(BT_HDR *p_msg)
|
||||
{
|
||||
UINT8 index = BTA_HH_IDX_INVALID;
|
||||
tBTA_HH_DEV_CB *p_cb = NULL;
|
||||
|
||||
switch (p_msg->event) {
|
||||
case BTA_HH_API_ENABLE_EVT:
|
||||
bta_hh_api_enable((tBTA_HH_DATA *) p_msg);
|
||||
break;
|
||||
|
||||
case BTA_HH_API_DISABLE_EVT:
|
||||
bta_hh_api_disable();
|
||||
break;
|
||||
|
||||
case BTA_HH_DISC_CMPL_EVT: /* disable complete */
|
||||
bta_hh_disc_cmpl();
|
||||
break;
|
||||
|
||||
default:
|
||||
/* all events processed in state machine need to find corresponding
|
||||
CB before proceed */
|
||||
if (p_msg->event == BTA_HH_API_OPEN_EVT) {
|
||||
index = bta_hh_find_cb(((tBTA_HH_API_CONN *)p_msg)->bd_addr);
|
||||
} else if (p_msg->event == BTA_HH_API_MAINT_DEV_EVT) {
|
||||
/* if add device */
|
||||
if (((tBTA_HH_MAINT_DEV *)p_msg)->sub_event == BTA_HH_ADD_DEV_EVT) {
|
||||
index = bta_hh_find_cb(((tBTA_HH_MAINT_DEV *)p_msg)->bda);
|
||||
} else { /* else remove device by handle */
|
||||
index = bta_hh_dev_handle_to_cb_idx((UINT8)p_msg->layer_specific);
|
||||
// btla-specific ++
|
||||
/* If BT disable is done while the HID device is connected and Link_Key uses unauthenticated combination
|
||||
* then we can get into a situation where remove_bonding is called with the index set to 0 (without getting
|
||||
* cleaned up). Only when VIRTUAL_UNPLUG is called do we cleanup the index and make it MAX_KNOWN.
|
||||
* So if REMOVE_DEVICE is called and in_use is FALSE then we should treat this as a NULL p_cb. Hence we
|
||||
* force the index to be IDX_INVALID
|
||||
*/
|
||||
if ((index != BTA_HH_IDX_INVALID) &&
|
||||
(bta_hh_cb.kdev[index].in_use == FALSE)) {
|
||||
index = BTA_HH_IDX_INVALID;
|
||||
}
|
||||
// btla-specific --
|
||||
}
|
||||
} else if (p_msg->event == BTA_HH_INT_OPEN_EVT) {
|
||||
index = bta_hh_find_cb(((tBTA_HH_CBACK_DATA *)p_msg)->addr);
|
||||
} else {
|
||||
index = bta_hh_dev_handle_to_cb_idx((UINT8)p_msg->layer_specific);
|
||||
}
|
||||
|
||||
if (index != BTA_HH_IDX_INVALID) {
|
||||
p_cb = &bta_hh_cb.kdev[index];
|
||||
}
|
||||
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("bta_hh_hdl_event:: handle = %d dev_cb[%d] ", p_msg->layer_specific, index);
|
||||
#endif
|
||||
bta_hh_sm_execute(p_cb, p_msg->event, (tBTA_HH_DATA *) p_msg);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
** Debug Functions
|
||||
*****************************************************************************/
|
||||
#if BTA_HH_DEBUG
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_evt_code
|
||||
**
|
||||
** Description
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static char *bta_hh_evt_code(tBTA_HH_INT_EVT evt_code)
|
||||
{
|
||||
switch (evt_code) {
|
||||
case BTA_HH_API_DISABLE_EVT:
|
||||
return "BTA_HH_API_DISABLE_EVT";
|
||||
case BTA_HH_API_ENABLE_EVT:
|
||||
return "BTA_HH_API_ENABLE_EVT";
|
||||
case BTA_HH_API_OPEN_EVT:
|
||||
return "BTA_HH_API_OPEN_EVT";
|
||||
case BTA_HH_API_CLOSE_EVT:
|
||||
return "BTA_HH_API_CLOSE_EVT";
|
||||
case BTA_HH_INT_OPEN_EVT:
|
||||
return "BTA_HH_INT_OPEN_EVT";
|
||||
case BTA_HH_INT_CLOSE_EVT:
|
||||
return "BTA_HH_INT_CLOSE_EVT";
|
||||
case BTA_HH_INT_HANDSK_EVT:
|
||||
return "BTA_HH_INT_HANDSK_EVT";
|
||||
case BTA_HH_INT_DATA_EVT:
|
||||
return "BTA_HH_INT_DATA_EVT";
|
||||
case BTA_HH_INT_CTRL_DATA:
|
||||
return "BTA_HH_INT_CTRL_DATA";
|
||||
case BTA_HH_API_WRITE_DEV_EVT:
|
||||
return "BTA_HH_API_WRITE_DEV_EVT";
|
||||
case BTA_HH_SDP_CMPL_EVT:
|
||||
return "BTA_HH_SDP_CMPL_EVT";
|
||||
case BTA_HH_DISC_CMPL_EVT:
|
||||
return "BTA_HH_DISC_CMPL_EVT";
|
||||
case BTA_HH_API_MAINT_DEV_EVT:
|
||||
return "BTA_HH_API_MAINT_DEV_EVT";
|
||||
case BTA_HH_API_GET_DSCP_EVT:
|
||||
return "BTA_HH_API_GET_DSCP_EVT";
|
||||
case BTA_HH_OPEN_CMPL_EVT:
|
||||
return "BTA_HH_OPEN_CMPL_EVT";
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
case BTA_HH_GATT_CLOSE_EVT:
|
||||
return "BTA_HH_GATT_CLOSE_EVT";
|
||||
case BTA_HH_GATT_OPEN_EVT:
|
||||
return "BTA_HH_GATT_OPEN_EVT";
|
||||
case BTA_HH_START_ENC_EVT:
|
||||
return "BTA_HH_START_ENC_EVT";
|
||||
case BTA_HH_ENC_CMPL_EVT:
|
||||
return "BTA_HH_ENC_CMPL_EVT";
|
||||
case BTA_HH_GATT_READ_CHAR_CMPL_EVT:
|
||||
return "BTA_HH_GATT_READ_CHAR_CMPL_EVT";
|
||||
case BTA_HH_GATT_WRITE_CHAR_CMPL_EVT:
|
||||
return "BTA_HH_GATT_WRITE_CHAR_CMPL_EVT";
|
||||
case BTA_HH_GATT_READ_DESCR_CMPL_EVT:
|
||||
return "BTA_HH_GATT_READ_DESCR_CMPL_EVT";
|
||||
case BTA_HH_GATT_WRITE_DESCR_CMPL_EVT:
|
||||
return "BTA_HH_GATT_WRITE_DESCR_CMPL_EVT";
|
||||
#endif
|
||||
default:
|
||||
return "unknown HID Host event code";
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_state_code
|
||||
**
|
||||
** Description get string representation of HID host state code.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static char *bta_hh_state_code(tBTA_HH_STATE state_code)
|
||||
{
|
||||
switch (state_code) {
|
||||
case BTA_HH_NULL_ST:
|
||||
return"BTA_HH_NULL_ST";
|
||||
case BTA_HH_IDLE_ST:
|
||||
return "BTA_HH_IDLE_ST";
|
||||
case BTA_HH_W4_CONN_ST:
|
||||
return "BTA_HH_W4_CONN_ST";
|
||||
case BTA_HH_CONN_ST:
|
||||
return "BTA_HH_CONN_ST";
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
case BTA_HH_W4_SEC:
|
||||
return "BTA_HH_W4_SEC";
|
||||
#endif
|
||||
default:
|
||||
return "unknown HID Host state";
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Debug Functions */
|
||||
|
||||
#endif /* BTA_HH_INCLUDED */
|
||||
524
components/bt/bluedroid/bta/hh/bta_hh_utils.c
Normal file
524
components/bt/bluedroid/bta/hh/bta_hh_utils.c
Normal file
@@ -0,0 +1,524 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include <string.h>
|
||||
|
||||
#include "bt_target.h"
|
||||
#if defined(BTA_HH_INCLUDED) && (BTA_HH_INCLUDED == TRUE)
|
||||
|
||||
|
||||
#include "bta_hh_int.h"
|
||||
|
||||
/* if SSR max latency is not defined by remote device, set the default value
|
||||
as half of the link supervision timeout */
|
||||
#define BTA_HH_GET_DEF_SSR_MAX_LAT(x) ((x)>> 1)
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
#define BTA_HH_KB_CTRL_MASK 0x11
|
||||
#define BTA_HH_KB_SHIFT_MASK 0x22
|
||||
#define BTA_HH_KB_ALT_MASK 0x44
|
||||
#define BTA_HH_KB_GUI_MASK 0x88
|
||||
|
||||
#define BTA_HH_KB_CAPS_LOCK 0x39 /* caps lock */
|
||||
#define BTA_HH_KB_NUM_LOCK 0x53 /* num lock */
|
||||
|
||||
|
||||
#define BTA_HH_MAX_RPT_CHARS 8
|
||||
|
||||
static const UINT8 bta_hh_mod_key_mask[BTA_HH_MOD_MAX_KEY] = {
|
||||
BTA_HH_KB_CTRL_MASK,
|
||||
BTA_HH_KB_SHIFT_MASK,
|
||||
BTA_HH_KB_ALT_MASK,
|
||||
BTA_HH_KB_GUI_MASK
|
||||
};
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_find_cb
|
||||
**
|
||||
** Description Find best available control block according to BD address.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT8 bta_hh_find_cb(BD_ADDR bda)
|
||||
{
|
||||
UINT8 xx;
|
||||
|
||||
/* See how many active devices there are. */
|
||||
for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
|
||||
/* check if any active/known devices is a match */
|
||||
if ((!bdcmp (bda, bta_hh_cb.kdev[xx].addr) &&
|
||||
bdcmp(bda, bd_addr_null) != 0) ) {
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("found kdev_cb[%d] hid_handle = %d ", xx,
|
||||
bta_hh_cb.kdev[xx].hid_handle)
|
||||
#endif
|
||||
return xx;
|
||||
}
|
||||
#if BTA_HH_DEBUG
|
||||
else
|
||||
APPL_TRACE_DEBUG("in_use ? [%d] kdev[%d].hid_handle = %d state = [%d]",
|
||||
bta_hh_cb.kdev[xx].in_use, xx,
|
||||
bta_hh_cb.kdev[xx].hid_handle,
|
||||
bta_hh_cb.kdev[xx].state);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* if no active device match, find a spot for it */
|
||||
for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
|
||||
if (!bta_hh_cb.kdev[xx].in_use) {
|
||||
bdcpy(bta_hh_cb.kdev[xx].addr, bda);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* If device list full, report BTA_HH_IDX_INVALID */
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("bta_hh_find_cb:: index = %d while max = %d",
|
||||
xx, BTA_HH_MAX_DEVICE);
|
||||
#endif
|
||||
|
||||
if (xx == BTA_HH_MAX_DEVICE) {
|
||||
xx = BTA_HH_IDX_INVALID;
|
||||
}
|
||||
|
||||
return xx;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_clean_up_kdev
|
||||
**
|
||||
** Description Clean up device control block when device is removed from
|
||||
** manitainace list, and update control block index map.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_clean_up_kdev(tBTA_HH_DEV_CB *p_cb)
|
||||
{
|
||||
UINT8 index;
|
||||
|
||||
if (p_cb->hid_handle != BTA_HH_INVALID_HANDLE ) {
|
||||
#if BTA_HH_LE_INCLUDED == TRUE
|
||||
if (p_cb->is_le_device) {
|
||||
bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(p_cb->hid_handle)] = BTA_HH_IDX_INVALID;
|
||||
} else
|
||||
#endif
|
||||
bta_hh_cb.cb_index[p_cb->hid_handle] = BTA_HH_IDX_INVALID;
|
||||
}
|
||||
|
||||
/* reset device control block */
|
||||
index = p_cb->index; /* Preserve index for this control block */
|
||||
|
||||
/* Free buffer for report descriptor info */
|
||||
utl_freebuf((void **)&p_cb->dscp_info.descriptor.dsc_list);
|
||||
|
||||
memset(p_cb, 0, sizeof (tBTA_HH_DEV_CB)); /* Reset control block */
|
||||
|
||||
p_cb->index = index; /* Restore index for this control block */
|
||||
p_cb->state = BTA_HH_IDLE_ST;
|
||||
p_cb->hid_handle = BTA_HH_INVALID_HANDLE;
|
||||
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_update_di_info
|
||||
**
|
||||
** Description Maintain a known device list for BTA HH.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_update_di_info(tBTA_HH_DEV_CB *p_cb, UINT16 vendor_id, UINT16 product_id,
|
||||
UINT16 version, UINT8 flag)
|
||||
{
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("vendor_id = 0x%2x product_id = 0x%2x version = 0x%2x",
|
||||
vendor_id, product_id, version);
|
||||
#endif
|
||||
p_cb->dscp_info.vendor_id = vendor_id;
|
||||
p_cb->dscp_info.product_id = product_id;
|
||||
p_cb->dscp_info.version = version;
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
p_cb->dscp_info.flag = flag;
|
||||
#else
|
||||
UNUSED(flag);
|
||||
#endif
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_add_device_to_list
|
||||
**
|
||||
** Description Maintain a known device list for BTA HH.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_add_device_to_list(tBTA_HH_DEV_CB *p_cb, UINT8 handle,
|
||||
UINT16 attr_mask,
|
||||
tHID_DEV_DSCP_INFO *p_dscp_info,
|
||||
UINT8 sub_class,
|
||||
UINT16 ssr_max_latency,
|
||||
UINT16 ssr_min_tout,
|
||||
UINT8 app_id)
|
||||
{
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("subclass = 0x%2x", sub_class);
|
||||
#endif
|
||||
|
||||
p_cb->hid_handle = handle;
|
||||
p_cb->in_use = TRUE;
|
||||
p_cb->attr_mask = attr_mask;
|
||||
|
||||
p_cb->sub_class = sub_class;
|
||||
p_cb->app_id = app_id;
|
||||
|
||||
p_cb->dscp_info.ssr_max_latency = ssr_max_latency;
|
||||
p_cb->dscp_info.ssr_min_tout = ssr_min_tout;
|
||||
|
||||
/* store report descriptor info */
|
||||
if ( p_dscp_info) {
|
||||
utl_freebuf((void **)&p_cb->dscp_info.descriptor.dsc_list);
|
||||
|
||||
if (p_dscp_info->dl_len &&
|
||||
(p_cb->dscp_info.descriptor.dsc_list =
|
||||
(UINT8 *)GKI_getbuf(p_dscp_info->dl_len)) != NULL) {
|
||||
p_cb->dscp_info.descriptor.dl_len = p_dscp_info->dl_len;
|
||||
memcpy(p_cb->dscp_info.descriptor.dsc_list, p_dscp_info->dsc_list,
|
||||
p_dscp_info->dl_len);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_tod_spt
|
||||
**
|
||||
** Description Check to see if this type of device is supported
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_hh_tod_spt(tBTA_HH_DEV_CB *p_cb, UINT8 sub_class)
|
||||
{
|
||||
UINT8 xx;
|
||||
UINT8 cod = (sub_class >> 2); /* lower two bits are reserved */
|
||||
|
||||
for (xx = 0 ; xx < p_bta_hh_cfg->max_devt_spt; xx ++) {
|
||||
if (cod == (UINT8) p_bta_hh_cfg->p_devt_list[xx].tod) {
|
||||
p_cb->app_id = p_bta_hh_cfg->p_devt_list[xx].app_id;
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_EVENT("bta_hh_tod_spt sub_class:0x%x supported", sub_class);
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_EVENT("bta_hh_tod_spt sub_class:0x%x NOT supported", sub_class);
|
||||
#endif
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_parse_keybd_rpt
|
||||
**
|
||||
** Description This utility function parse a boot mode keyboard report.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_parse_keybd_rpt(tBTA_HH_BOOT_RPT *p_kb_data, UINT8 *p_report,
|
||||
UINT16 report_len)
|
||||
{
|
||||
tBTA_HH_KB_CB *p_kb = &bta_hh_cb.kb_cb;
|
||||
tBTA_HH_KEYBD_RPT *p_data = &p_kb_data->data_rpt.keybd_rpt;
|
||||
|
||||
UINT8 this_char, ctl_shift;
|
||||
UINT16 xx, yy, key_idx = 0;
|
||||
UINT8 this_report[BTA_HH_MAX_RPT_CHARS];
|
||||
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("bta_hh_parse_keybd_rpt: (report=%p, report_len=%d) called",
|
||||
p_report, report_len);
|
||||
#endif
|
||||
|
||||
if (report_len < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
ctl_shift = *p_report++;
|
||||
report_len--;
|
||||
|
||||
if (report_len > BTA_HH_MAX_RPT_CHARS) {
|
||||
report_len = BTA_HH_MAX_RPT_CHARS;
|
||||
}
|
||||
|
||||
memset (this_report, 0, BTA_HH_MAX_RPT_CHARS);
|
||||
memset (p_data, 0, sizeof(tBTA_HH_KEYBD_RPT));
|
||||
memcpy (this_report, p_report, report_len);
|
||||
|
||||
/* Take care of shift, control, GUI and alt, modifier keys */
|
||||
for (xx = 0; xx < BTA_HH_MOD_MAX_KEY; xx ++ ) {
|
||||
if (ctl_shift & bta_hh_mod_key_mask[xx]) {
|
||||
APPL_TRACE_DEBUG("Mod Key[%02x] pressed", bta_hh_mod_key_mask[xx] );
|
||||
p_kb->mod_key[xx] = TRUE;
|
||||
} else if (p_kb->mod_key[xx]) {
|
||||
p_kb->mod_key[xx] = FALSE;
|
||||
}
|
||||
/* control key flag is set */
|
||||
p_data->mod_key[xx] = p_kb->mod_key[xx];
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
/* First step is to remove all characters we saw in the last report */
|
||||
/***************************************************************************/
|
||||
for (xx = 0; xx < report_len; xx++) {
|
||||
for (yy = 0; yy < BTA_HH_MAX_RPT_CHARS; yy++) {
|
||||
if (this_report[xx] == p_kb->last_report[yy]) {
|
||||
this_report[xx] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/***************************************************************************/
|
||||
/* Now, process all the characters in the report, up to 6 keycodes */
|
||||
/***************************************************************************/
|
||||
for (xx = 0; xx < report_len; xx++) {
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("this_char = %02x", this_report[xx]);
|
||||
#endif
|
||||
if ((this_char = this_report[xx]) == 0) {
|
||||
continue;
|
||||
}
|
||||
/* take the key code as the report data */
|
||||
if (this_report[xx] == BTA_HH_KB_CAPS_LOCK) {
|
||||
p_kb->caps_lock = p_kb->caps_lock ? FALSE : TRUE;
|
||||
} else if (this_report[xx] == BTA_HH_KB_NUM_LOCK) {
|
||||
p_kb->num_lock = p_kb->num_lock ? FALSE : TRUE;
|
||||
} else {
|
||||
p_data->this_char[key_idx ++] = this_char;
|
||||
}
|
||||
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("found keycode %02x ", this_report[xx]);
|
||||
#endif
|
||||
p_data->caps_lock = p_kb->caps_lock;
|
||||
p_data->num_lock = p_kb->num_lock;
|
||||
}
|
||||
|
||||
memset (p_kb->last_report, 0, BTA_HH_MAX_RPT_CHARS);
|
||||
memcpy (p_kb->last_report, p_report, report_len);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_parse_mice_rpt
|
||||
**
|
||||
** Description This utility function parse a boot mode mouse report.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_parse_mice_rpt(tBTA_HH_BOOT_RPT *p_mice_data, UINT8 *p_report,
|
||||
UINT16 report_len)
|
||||
{
|
||||
tBTA_HH_MICE_RPT *p_data = &p_mice_data->data_rpt.mice_rpt;
|
||||
#if BTA_HH_DEBUG
|
||||
UINT8 xx;
|
||||
|
||||
APPL_TRACE_DEBUG("bta_hh_parse_mice_rpt: bta_keybd_rpt_rcvd(report=%p, \
|
||||
report_len=%d) called", p_report, report_len);
|
||||
#endif
|
||||
|
||||
if (report_len < 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (report_len > BTA_HH_MAX_RPT_CHARS) {
|
||||
report_len = BTA_HH_MAX_RPT_CHARS;
|
||||
}
|
||||
|
||||
#if BTA_HH_DEBUG
|
||||
for (xx = 0; xx < report_len; xx++) {
|
||||
APPL_TRACE_DEBUG("this_char = %02x", p_report[xx]);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* only first bytes lower 3 bits valid */
|
||||
p_data->mouse_button = (p_report[0] & 0x07);
|
||||
|
||||
/* x displacement */
|
||||
p_data->delta_x = p_report[1];
|
||||
|
||||
/* y displacement */
|
||||
p_data->delta_y = p_report[2];
|
||||
|
||||
#if BTA_HH_DEBUG
|
||||
APPL_TRACE_DEBUG("mice button: 0x%2x", p_data->mouse_button);
|
||||
APPL_TRACE_DEBUG("mice move: x = %d y = %d", p_data->delta_x,
|
||||
p_data->delta_y );
|
||||
#endif
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_read_ssr_param
|
||||
**
|
||||
** Description Read the SSR Parameter for the remote device
|
||||
**
|
||||
** Returns tBTA_HH_STATUS operation status
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_HH_STATUS bta_hh_read_ssr_param(BD_ADDR bd_addr, UINT16 *p_max_ssr_lat, UINT16 *p_min_ssr_tout)
|
||||
{
|
||||
tBTA_HH_STATUS status = BTA_HH_ERR;
|
||||
tBTA_HH_CB *p_cb = &bta_hh_cb;
|
||||
UINT8 i;
|
||||
UINT16 ssr_max_latency;
|
||||
for (i = 0; i < BTA_HH_MAX_KNOWN; i ++) {
|
||||
if (memcmp(p_cb->kdev[i].addr, bd_addr, BD_ADDR_LEN) == 0) {
|
||||
|
||||
/* if remote device does not have HIDSSRHostMaxLatency attribute in SDP,
|
||||
set SSR max latency default value here. */
|
||||
if (p_cb->kdev[i].dscp_info.ssr_max_latency == HID_SSR_PARAM_INVALID) {
|
||||
/* The default is calculated as half of link supervision timeout.*/
|
||||
|
||||
BTM_GetLinkSuperTout(p_cb->kdev[i].addr, &ssr_max_latency) ;
|
||||
ssr_max_latency = BTA_HH_GET_DEF_SSR_MAX_LAT(ssr_max_latency);
|
||||
|
||||
/* per 1.1 spec, if the newly calculated max latency is greater than
|
||||
BTA_HH_SSR_MAX_LATENCY_DEF which is 500ms, use BTA_HH_SSR_MAX_LATENCY_DEF */
|
||||
if (ssr_max_latency > BTA_HH_SSR_MAX_LATENCY_DEF) {
|
||||
ssr_max_latency = BTA_HH_SSR_MAX_LATENCY_DEF;
|
||||
}
|
||||
|
||||
* p_max_ssr_lat = ssr_max_latency;
|
||||
} else {
|
||||
* p_max_ssr_lat = p_cb->kdev[i].dscp_info.ssr_max_latency;
|
||||
}
|
||||
|
||||
if (p_cb->kdev[i].dscp_info.ssr_min_tout == HID_SSR_PARAM_INVALID) {
|
||||
* p_min_ssr_tout = BTA_HH_SSR_MIN_TOUT_DEF;
|
||||
} else {
|
||||
* p_min_ssr_tout = p_cb->kdev[i].dscp_info.ssr_min_tout;
|
||||
}
|
||||
|
||||
status = BTA_HH_OK;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_cleanup_disable
|
||||
**
|
||||
** Description when disable finished, cleanup control block and send callback
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_cleanup_disable(tBTA_HH_STATUS status)
|
||||
{
|
||||
UINT8 xx;
|
||||
/* free buffer in CB holding report descriptors */
|
||||
for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx ++) {
|
||||
utl_freebuf((void **)&bta_hh_cb.kdev[xx].dscp_info.descriptor.dsc_list);
|
||||
}
|
||||
utl_freebuf((void **)&bta_hh_cb.p_disc_db);
|
||||
|
||||
(* bta_hh_cb.p_cback)(BTA_HH_DISABLE_EVT, (tBTA_HH *)&status);
|
||||
/* all connections are down, no waiting for diconnect */
|
||||
memset(&bta_hh_cb, 0, sizeof(tBTA_HH_CB));
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_dev_handle_to_cb_idx
|
||||
**
|
||||
** Description convert a HID device handle to the device control block index.
|
||||
**
|
||||
**
|
||||
** Returns UINT8: index of the device control block.
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT8 bta_hh_dev_handle_to_cb_idx(UINT8 dev_handle)
|
||||
{
|
||||
UINT8 index = BTA_HH_IDX_INVALID;
|
||||
|
||||
#if BTA_HH_LE_INCLUDED == TRUE
|
||||
if (BTA_HH_IS_LE_DEV_HDL(dev_handle)) {
|
||||
if (BTA_HH_IS_LE_DEV_HDL_VALID(dev_handle)) {
|
||||
index = bta_hh_cb.le_cb_index[BTA_HH_GET_LE_CB_IDX(dev_handle)];
|
||||
}
|
||||
#if BTA_HH_DEBUG == TRUE
|
||||
APPL_TRACE_DEBUG("bta_hh_dev_handle_to_cb_idx dev_handle = %d index = %d", dev_handle, index);
|
||||
#endif
|
||||
} else
|
||||
#endif
|
||||
/* regular HID device checking */
|
||||
if (dev_handle < BTA_HH_MAX_KNOWN ) {
|
||||
index = bta_hh_cb.cb_index[dev_handle];
|
||||
}
|
||||
|
||||
return index;
|
||||
|
||||
}
|
||||
#if BTA_HH_DEBUG
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_trace_dev_db
|
||||
**
|
||||
** Description Check to see if this type of device is supported
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_hh_trace_dev_db(void)
|
||||
{
|
||||
UINT8 xx;
|
||||
|
||||
APPL_TRACE_DEBUG("bta_hh_trace_dev_db:: Device DB list********************");
|
||||
|
||||
for (xx = 0; xx < BTA_HH_MAX_DEVICE; xx++) {
|
||||
APPL_TRACE_DEBUG("kdev[%d] in_use[%d] handle[%d] ", xx,
|
||||
bta_hh_cb.kdev[xx].in_use, bta_hh_cb.kdev[xx].hid_handle);
|
||||
|
||||
APPL_TRACE_DEBUG("\t\t\t attr_mask[%04x] state [%d] sub_class[%02x] index = %d",
|
||||
bta_hh_cb.kdev[xx].attr_mask, bta_hh_cb.kdev[xx].state,
|
||||
bta_hh_cb.kdev[xx].sub_class, bta_hh_cb.kdev[xx].index);
|
||||
}
|
||||
APPL_TRACE_DEBUG("*********************************************************");
|
||||
}
|
||||
#endif
|
||||
#endif /* HL_INCLUDED */
|
||||
2367
components/bt/bluedroid/bta/include/bta_api.h
Normal file
2367
components/bt/bluedroid/bta/include/bta_api.h
Normal file
File diff suppressed because it is too large
Load Diff
80
components/bt/bluedroid/bta/include/bta_dm_ci.h
Normal file
80
components/bt/bluedroid/bta/include/bta_dm_ci.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2006-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the interface file for device mananger call-in functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_DM_CI_H
|
||||
#define BTA_DM_CI_H
|
||||
|
||||
#include "bta_api.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Function Declarations
|
||||
*****************************************************************************/
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_ci_io_req
|
||||
**
|
||||
** Description This function must be called in response to function
|
||||
** bta_dm_co_io_req(), if *p_oob_data is set to BTA_OOB_UNKNOWN
|
||||
** by bta_dm_co_io_req().
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_ci_io_req(BD_ADDR bd_addr, tBTA_IO_CAP io_cap,
|
||||
tBTA_OOB_DATA oob_data, tBTA_AUTH_REQ auth_req);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_ci_rmt_oob
|
||||
**
|
||||
** Description This function must be called in response to function
|
||||
** bta_dm_co_rmt_oob() to provide the OOB data associated
|
||||
** with the remote device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_ci_rmt_oob(BOOLEAN accept, BD_ADDR bd_addr,
|
||||
BT_OCTET16 c, BT_OCTET16 r);
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sco_ci_data_ready
|
||||
**
|
||||
** Description This function sends an event to indicating that the phone
|
||||
** has SCO data ready..
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_sco_ci_data_ready(UINT16 event, UINT16 sco_handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
273
components/bt/bluedroid/bta/include/bta_dm_co.h
Normal file
273
components/bt/bluedroid/bta/include/bta_dm_co.h
Normal file
@@ -0,0 +1,273 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2006-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the interface file for device mananger callout functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_DM_CO_H
|
||||
#define BTA_DM_CO_H
|
||||
|
||||
#include "bta_sys.h"
|
||||
|
||||
|
||||
#ifndef BTA_SCO_OUT_PKT_SIZE
|
||||
#define BTA_SCO_OUT_PKT_SIZE BTM_SCO_DATA_SIZE_MAX
|
||||
#endif
|
||||
|
||||
#define BTA_SCO_CODEC_PCM 0 /* used for regular SCO */
|
||||
#define BTA_SCO_CODEC_SBC 1 /* used for WBS */
|
||||
typedef UINT8 tBTA_SCO_CODEC_TYPE;
|
||||
|
||||
#define BTA_DM_SCO_SAMP_RATE_8K 8000
|
||||
#define BTA_DM_SCO_SAMP_RATE_16K 16000
|
||||
|
||||
/* SCO codec information */
|
||||
typedef struct {
|
||||
tBTA_SCO_CODEC_TYPE codec_type;
|
||||
} tBTA_CODEC_INFO;
|
||||
|
||||
#define BTA_DM_SCO_ROUTE_PCM BTM_SCO_ROUTE_PCM
|
||||
#define BTA_DM_SCO_ROUTE_HCI BTM_SCO_ROUTE_HCI
|
||||
|
||||
typedef tBTM_SCO_ROUTE_TYPE tBTA_DM_SCO_ROUTE_TYPE;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Function Declarations
|
||||
*****************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_co_io_req
|
||||
**
|
||||
** Description This callout function is executed by DM to get IO capabilities
|
||||
** of the local device for the Simple Pairing process
|
||||
**
|
||||
** Parameters bd_addr - The peer device
|
||||
** *p_io_cap - The local Input/Output capabilities
|
||||
** *p_oob_data - TRUE, if OOB data is available for the peer device.
|
||||
** *p_auth_req - TRUE, if MITM protection is required.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_co_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap,
|
||||
tBTA_OOB_DATA *p_oob_data, tBTA_AUTH_REQ *p_auth_req,
|
||||
BOOLEAN is_orig);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_co_io_rsp
|
||||
**
|
||||
** Description This callout function is executed by DM to report IO capabilities
|
||||
** of the peer device for the Simple Pairing process
|
||||
**
|
||||
** Parameters bd_addr - The peer device
|
||||
** io_cap - The remote Input/Output capabilities
|
||||
** oob_data - TRUE, if OOB data is available for the peer device.
|
||||
** auth_req - TRUE, if MITM protection is required.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_co_io_rsp(BD_ADDR bd_addr, tBTA_IO_CAP io_cap,
|
||||
tBTA_OOB_DATA oob_data, tBTA_AUTH_REQ auth_req);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_co_lk_upgrade
|
||||
**
|
||||
** Description This callout function is executed by DM to check if the
|
||||
** platform wants allow link key upgrade
|
||||
**
|
||||
** Parameters bd_addr - The peer device
|
||||
** *p_upgrade - TRUE, if link key upgrade is desired.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_co_lk_upgrade(BD_ADDR bd_addr, BOOLEAN *p_upgrade );
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_co_loc_oob
|
||||
**
|
||||
** Description This callout function is executed by DM to report the OOB
|
||||
** data of the local device for the Simple Pairing process
|
||||
**
|
||||
** Parameters valid - TRUE, if the local OOB data is retrieved from LM
|
||||
** c - Simple Pairing Hash C
|
||||
** r - Simple Pairing Randomnizer R
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_co_loc_oob(BOOLEAN valid, BT_OCTET16 c, BT_OCTET16 r);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_co_rmt_oob
|
||||
**
|
||||
** Description This callout function is executed by DM to request the OOB
|
||||
** data for the remote device for the Simple Pairing process
|
||||
**
|
||||
** Parameters bd_addr - The peer device
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_co_rmt_oob(BD_ADDR bd_addr);
|
||||
|
||||
/*****************************************************************************
|
||||
** SCO over HCI Function Declarations
|
||||
*****************************************************************************/
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sco_co_init
|
||||
**
|
||||
** Description This function can be used by the phone to initialize audio
|
||||
** codec or for other initialization purposes before SCO connection
|
||||
** is opened.
|
||||
**
|
||||
**
|
||||
** Returns Void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern tBTA_DM_SCO_ROUTE_TYPE bta_dm_sco_co_init(UINT32 rx_bw, UINT32 tx_bw,
|
||||
tBTA_CODEC_INFO *p_codec_info, UINT8 app_id);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sco_co_open
|
||||
**
|
||||
** Description This function is executed when a SCO connection is open.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_sco_co_open(UINT16 handle, UINT8 pkt_size, UINT16 event);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sco_co_close
|
||||
**
|
||||
** Description This function is called when a SCO connection is closed
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_sco_co_close(void);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sco_co_out_data
|
||||
**
|
||||
** Description This function is called to send SCO data over HCI.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_sco_co_out_data(BT_HDR **p_buf);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sco_co_in_data
|
||||
**
|
||||
** Description This function is called to send incoming SCO data to application.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_sco_co_in_data(BT_HDR *p_buf, tBTM_SCO_DATA_FLAG status);
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_co_ble_io_req
|
||||
**
|
||||
** Description This callout function is executed by DM to get BLE IO capabilities
|
||||
** before SMP pairing gets going.
|
||||
**
|
||||
** Parameters bd_addr - The peer device
|
||||
** *p_io_cap - The local Input/Output capabilities
|
||||
** *p_oob_data - TRUE, if OOB data is available for the peer device.
|
||||
** *p_auth_req - Auth request setting (Bonding and MITM required or not)
|
||||
** *p_max_key_size - max key size local device supported.
|
||||
** *p_init_key - initiator keys.
|
||||
** *p_resp_key - responder keys.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_co_ble_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap,
|
||||
tBTA_OOB_DATA *p_oob_data,
|
||||
tBTA_LE_AUTH_REQ *p_auth_req,
|
||||
UINT8 *p_max_key_size,
|
||||
tBTA_LE_KEY_TYPE *p_init_key,
|
||||
tBTA_LE_KEY_TYPE *p_resp_key );
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_co_ble_local_key_reload
|
||||
**
|
||||
** Description This callout function is to load the local BLE keys if available
|
||||
** on the device.
|
||||
**
|
||||
** Parameters none
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_co_ble_load_local_keys (tBTA_DM_BLE_LOCAL_KEY_MASK *p_key_mask, BT_OCTET16 er,
|
||||
tBTA_BLE_LOCAL_ID_KEYS *p_id_keys);
|
||||
|
||||
// btla-specific ++
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_co_ble_io_req
|
||||
**
|
||||
** Description This callout function is executed by DM to get BLE IO capabilities
|
||||
** before SMP pairing gets going.
|
||||
**
|
||||
** Parameters bd_addr - The peer device
|
||||
** *p_io_cap - The local Input/Output capabilities
|
||||
** *p_oob_data - TRUE, if OOB data is available for the peer device.
|
||||
** *p_auth_req - Auth request setting (Bonding and MITM required or not)
|
||||
** *p_max_key_size - max key size local device supported.
|
||||
** *p_init_key - initiator keys.
|
||||
** *p_resp_key - responder keys.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_dm_co_ble_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap,
|
||||
tBTA_OOB_DATA *p_oob_data,
|
||||
tBTA_LE_AUTH_REQ *p_auth_req,
|
||||
UINT8 *p_max_key_size,
|
||||
tBTA_LE_KEY_TYPE *p_init_key,
|
||||
tBTA_LE_KEY_TYPE *p_resp_key );
|
||||
// btla-specific --
|
||||
|
||||
#endif
|
||||
1372
components/bt/bluedroid/bta/include/bta_gatt_api.h
Normal file
1372
components/bt/bluedroid/bta/include/bta_gatt_api.h
Normal file
File diff suppressed because it is too large
Load Diff
117
components/bt/bluedroid/bta/include/bta_gattc_ci.h
Normal file
117
components/bt/bluedroid/bta/include/bta_gattc_ci.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the interface file for GATT call-in functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_GATTC_CI_H
|
||||
#define BTA_GATTC_CI_H
|
||||
|
||||
#include "bta_gatt_api.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and data types
|
||||
*****************************************************************************/
|
||||
|
||||
/* Open Complete Event */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATT_STATUS status;
|
||||
} tBTA_GATTC_CI_EVT;
|
||||
|
||||
#define BTA_GATTC_NV_LOAD_MAX 10
|
||||
|
||||
/* Read Ready Event */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATT_STATUS status;
|
||||
UINT16 num_attr;
|
||||
tBTA_GATTC_NV_ATTR attr[BTA_GATTC_NV_LOAD_MAX];
|
||||
} tBTA_GATTC_CI_LOAD;
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Function Declarations
|
||||
*****************************************************************************/
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_ci_cache_open
|
||||
**
|
||||
** Description This function sends an event to indicate server cache open
|
||||
** completed.
|
||||
**
|
||||
** Parameters server_bda - server BDA of this cache.
|
||||
** status - BTA_GATT_OK if full buffer of data,
|
||||
** BTA_GATT_FAIL if an error has occurred.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_gattc_ci_cache_open(BD_ADDR server_bda, UINT16 evt,
|
||||
tBTA_GATT_STATUS status, UINT16 conn_id);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_ci_cache_load
|
||||
**
|
||||
** Description This function sends an event to BTA indicating the phone has
|
||||
** load the servere cache and ready to send it to the stack.
|
||||
**
|
||||
** Parameters server_bda - server BDA of this cache.
|
||||
** num_bytes_read - number of bytes read into the buffer
|
||||
** specified in the read callout-function.
|
||||
** status - BTA_GATT_OK if full buffer of data,
|
||||
** BTA_GATT_FAIL if an error has occurred.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_gattc_ci_cache_load(BD_ADDR server_bda, UINT16 evt,
|
||||
UINT16 num_attr, tBTA_GATTC_NV_ATTR *p_atrr,
|
||||
tBTA_GATT_STATUS status, UINT16 conn_id);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_ci_save
|
||||
**
|
||||
** Description This function sends an event to BTA indicating the phone has
|
||||
** save the server cache.
|
||||
**
|
||||
** Parameters server_bda - server BDA of this cache.
|
||||
** status - BTA_GATT_OK if full buffer of data,
|
||||
** BTA_GATT_FAIL if an error has occurred.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_gattc_ci_cache_save(BD_ADDR server_bda, UINT16 evt,
|
||||
tBTA_GATT_STATUS status, UINT16 conn_id);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BTA_GATTC_CI_H */
|
||||
114
components/bt/bluedroid/bta/include/bta_gattc_co.h
Normal file
114
components/bt/bluedroid/bta/include/bta_gattc_co.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009-2013 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the interface file for BTA GATT client call-out functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_GATTC_CO_H
|
||||
#define BTA_GATTC_CO_H
|
||||
|
||||
#include "bta_gatt_api.h"
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_co_cache_open
|
||||
**
|
||||
** Description This callout function is executed by GATTC when a GATT server
|
||||
** cache is ready to be sent.
|
||||
**
|
||||
** Parameter server_bda: server bd address of this cache belongs to
|
||||
** evt: call in event to be passed in when cache open is done.
|
||||
** conn_id: connection ID of this cache operation attach to.
|
||||
** to_save: open cache to save or to load.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_gattc_co_cache_open(BD_ADDR server_bda, UINT16 evt,
|
||||
UINT16 conn_id, BOOLEAN to_save);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_co_cache_close
|
||||
**
|
||||
** Description This callout function is executed by GATTC when a GATT server
|
||||
** cache is written completely.
|
||||
**
|
||||
** Parameter server_bda: server bd address of this cache belongs to
|
||||
** conn_id: connection ID of this cache operation attach to.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_gattc_co_cache_close(BD_ADDR server_bda, UINT16 conn_id);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_co_cache_save
|
||||
**
|
||||
** Description This callout function is executed by GATT when a server cache
|
||||
** is available to save.
|
||||
**
|
||||
** Parameter server_bda: server bd address of this cache belongs to
|
||||
** evt: call in event to be passed in when cache save is done.
|
||||
** num_attr: number of attribute to be save.
|
||||
** p_attr: pointer to the list of attributes to save.
|
||||
** attr_index: starting attribute index of the save operation.
|
||||
** conn_id: connection ID of this cache operation attach to.
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_gattc_co_cache_save(BD_ADDR server_bda, UINT16 evt,
|
||||
UINT16 num_attr, tBTA_GATTC_NV_ATTR *p_attr,
|
||||
UINT16 attr_index, UINT16 conn_id);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_co_cache_load
|
||||
**
|
||||
** Description This callout function is executed by GATT when server cache
|
||||
** is required to load.
|
||||
**
|
||||
** Parameter server_bda: server bd address of this cache belongs to
|
||||
** evt: call in event to be passed in when cache save is done.
|
||||
** num_attr: number of attribute to be save.
|
||||
** attr_index: starting attribute index of the save operation.
|
||||
** conn_id: connection ID of this cache operation attach to.
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_gattc_co_cache_load(BD_ADDR server_bda, UINT16 evt,
|
||||
UINT16 start_index, UINT16 conn_id);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_co_cache_reset
|
||||
**
|
||||
** Description This callout function is executed by GATTC to reset cache in
|
||||
** application
|
||||
**
|
||||
** Parameter server_bda: server bd address of this cache belongs to
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_gattc_co_cache_reset(BD_ADDR server_bda);
|
||||
|
||||
#endif /* BTA_GATT_CO_H */
|
||||
525
components/bt/bluedroid/bta/include/bta_gattc_int.h
Normal file
525
components/bt/bluedroid/bta/include/bta_gattc_int.h
Normal file
@@ -0,0 +1,525 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the private file for the file transfer client (FTC).
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_GATTC_INT_H
|
||||
#define BTA_GATTC_INT_H
|
||||
|
||||
#include "bt_target.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_gatt_api.h"
|
||||
#include "bta_gattc_ci.h"
|
||||
#include "bta_gattc_co.h"
|
||||
|
||||
#include "gki.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and data types
|
||||
*****************************************************************************/
|
||||
enum {
|
||||
BTA_GATTC_API_OPEN_EVT = BTA_SYS_EVT_START(BTA_ID_GATTC),
|
||||
BTA_GATTC_INT_OPEN_FAIL_EVT,
|
||||
BTA_GATTC_API_CANCEL_OPEN_EVT,
|
||||
BTA_GATTC_INT_CANCEL_OPEN_OK_EVT,
|
||||
|
||||
BTA_GATTC_API_READ_EVT,
|
||||
BTA_GATTC_API_WRITE_EVT,
|
||||
BTA_GATTC_API_EXEC_EVT,
|
||||
BTA_GATTC_API_CFG_MTU_EVT,
|
||||
|
||||
BTA_GATTC_API_CLOSE_EVT,
|
||||
|
||||
BTA_GATTC_API_SEARCH_EVT,
|
||||
BTA_GATTC_API_CONFIRM_EVT,
|
||||
BTA_GATTC_API_READ_MULTI_EVT,
|
||||
BTA_GATTC_API_REFRESH_EVT,
|
||||
|
||||
BTA_GATTC_INT_CONN_EVT,
|
||||
BTA_GATTC_INT_DISCOVER_EVT,
|
||||
BTA_GATTC_DISCOVER_CMPL_EVT,
|
||||
BTA_GATTC_OP_CMPL_EVT,
|
||||
BTA_GATTC_INT_DISCONN_EVT,
|
||||
|
||||
/* for cache loading/saving */
|
||||
BTA_GATTC_START_CACHE_EVT,
|
||||
BTA_GATTC_CI_CACHE_OPEN_EVT,
|
||||
BTA_GATTC_CI_CACHE_LOAD_EVT,
|
||||
BTA_GATTC_CI_CACHE_SAVE_EVT,
|
||||
|
||||
BTA_GATTC_INT_START_IF_EVT,
|
||||
BTA_GATTC_API_REG_EVT,
|
||||
BTA_GATTC_API_DEREG_EVT,
|
||||
BTA_GATTC_API_LISTEN_EVT,
|
||||
BTA_GATTC_API_BROADCAST_EVT,
|
||||
BTA_GATTC_API_DISABLE_EVT,
|
||||
BTA_GATTC_ENC_CMPL_EVT
|
||||
};
|
||||
typedef UINT16 tBTA_GATTC_INT_EVT;
|
||||
|
||||
/* max client application GATTC can support */
|
||||
#ifndef BTA_GATTC_CL_MAX
|
||||
#define BTA_GATTC_CL_MAX 3 // 32
|
||||
#endif
|
||||
|
||||
/* max known devices GATTC can support */
|
||||
#ifndef BTA_GATTC_KNOWN_SR_MAX
|
||||
#define BTA_GATTC_KNOWN_SR_MAX 3 // 10
|
||||
#endif
|
||||
|
||||
#define BTA_GATTC_CONN_MAX GATT_MAX_PHY_CHANNEL
|
||||
|
||||
#ifndef BTA_GATTC_CLCB_MAX
|
||||
#define BTA_GATTC_CLCB_MAX GATT_CL_MAX_LCB
|
||||
#endif
|
||||
|
||||
#define BTA_GATTC_WRITE_PREPARE GATT_WRITE_PREPARE
|
||||
|
||||
|
||||
/* internal strucutre for GATTC register API */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBT_UUID app_uuid;
|
||||
tBTA_GATTC_CBACK *p_cback;
|
||||
} tBTA_GATTC_API_REG;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATTC_IF client_if;
|
||||
} tBTA_GATTC_INT_START_IF;
|
||||
|
||||
typedef tBTA_GATTC_INT_START_IF tBTA_GATTC_API_DEREG;
|
||||
typedef tBTA_GATTC_INT_START_IF tBTA_GATTC_INT_DEREG;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR remote_bda;
|
||||
tBTA_GATTC_IF client_if;
|
||||
BOOLEAN is_direct;
|
||||
tBTA_TRANSPORT transport;
|
||||
} tBTA_GATTC_API_OPEN;
|
||||
|
||||
typedef tBTA_GATTC_API_OPEN tBTA_GATTC_API_CANCEL_OPEN;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATT_AUTH_REQ auth_req;
|
||||
tBTA_GATT_SRVC_ID srvc_id;
|
||||
tBTA_GATT_ID char_id;
|
||||
tBTA_GATT_ID *p_descr_type;
|
||||
} tBTA_GATTC_API_READ;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATT_AUTH_REQ auth_req;
|
||||
tBTA_GATT_SRVC_ID srvc_id;
|
||||
tBTA_GATT_ID char_id;
|
||||
tBTA_GATT_ID *p_descr_type;
|
||||
tBTA_GATTC_WRITE_TYPE write_type;
|
||||
UINT16 offset;
|
||||
UINT16 len;
|
||||
UINT8 *p_value;
|
||||
} tBTA_GATTC_API_WRITE;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BOOLEAN is_execute;
|
||||
} tBTA_GATTC_API_EXEC;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATT_SRVC_ID srvc_id;
|
||||
tBTA_GATT_ID char_id;
|
||||
} tBTA_GATTC_API_CONFIRM;
|
||||
|
||||
typedef tGATT_CL_COMPLETE tBTA_GATTC_CMPL;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT8 op_code;
|
||||
tGATT_STATUS status;
|
||||
tBTA_GATTC_CMPL *p_cmpl;
|
||||
} tBTA_GATTC_OP_CMPL;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBT_UUID *p_srvc_uuid;
|
||||
} tBTA_GATTC_API_SEARCH;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATT_AUTH_REQ auth_req;
|
||||
UINT8 num_attr;
|
||||
tBTA_GATTC_ATTR_ID *p_id_list;
|
||||
} tBTA_GATTC_API_READ_MULTI;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR_PTR remote_bda;
|
||||
tBTA_GATTC_IF client_if;
|
||||
BOOLEAN start;
|
||||
} tBTA_GATTC_API_LISTEN;
|
||||
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT16 mtu;
|
||||
} tBTA_GATTC_API_CFG_MTU;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR remote_bda;
|
||||
tBTA_GATTC_IF client_if;
|
||||
UINT8 role;
|
||||
tBT_TRANSPORT transport;
|
||||
tGATT_DISCONN_REASON reason;
|
||||
} tBTA_GATTC_INT_CONN;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR remote_bda;
|
||||
tBTA_GATTC_IF client_if;
|
||||
} tBTA_GATTC_ENC_CMPL;
|
||||
|
||||
typedef union {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATTC_API_REG api_reg;
|
||||
tBTA_GATTC_API_DEREG api_dereg;
|
||||
tBTA_GATTC_API_OPEN api_conn;
|
||||
tBTA_GATTC_API_CANCEL_OPEN api_cancel_conn;
|
||||
tBTA_GATTC_API_READ api_read;
|
||||
tBTA_GATTC_API_SEARCH api_search;
|
||||
tBTA_GATTC_API_WRITE api_write;
|
||||
tBTA_GATTC_API_CONFIRM api_confirm;
|
||||
tBTA_GATTC_API_EXEC api_exec;
|
||||
tBTA_GATTC_API_READ_MULTI api_read_multi;
|
||||
tBTA_GATTC_API_CFG_MTU api_mtu;
|
||||
tBTA_GATTC_OP_CMPL op_cmpl;
|
||||
tBTA_GATTC_CI_EVT ci_open;
|
||||
tBTA_GATTC_CI_EVT ci_save;
|
||||
tBTA_GATTC_CI_LOAD ci_load;
|
||||
tBTA_GATTC_INT_CONN int_conn;
|
||||
tBTA_GATTC_ENC_CMPL enc_cmpl;
|
||||
|
||||
tBTA_GATTC_INT_START_IF int_start_if;
|
||||
tBTA_GATTC_INT_DEREG int_dereg;
|
||||
/* if peripheral role is supported */
|
||||
tBTA_GATTC_API_LISTEN api_listen;
|
||||
|
||||
} tBTA_GATTC_DATA;
|
||||
|
||||
|
||||
/* GATT server cache on the client */
|
||||
typedef union {
|
||||
UINT8 uuid128[LEN_UUID_128];
|
||||
UINT16 uuid16;
|
||||
} tBTA_GATTC_UUID;
|
||||
|
||||
typedef struct gattc_attr_cache {
|
||||
tBTA_GATTC_UUID *p_uuid;
|
||||
struct gattc_attr_cache *p_next;
|
||||
UINT16 uuid_len;
|
||||
UINT16 attr_handle;
|
||||
UINT8 inst_id;
|
||||
tBTA_GATT_CHAR_PROP property; /* if characteristic, it is char property;
|
||||
if included service, flag primary,
|
||||
if descriptor, not used */
|
||||
tBTA_GATTC_ATTR_TYPE attr_type;
|
||||
// btla-specific ++
|
||||
} __attribute__((packed)) tBTA_GATTC_CACHE_ATTR;
|
||||
// btla-specific --
|
||||
|
||||
typedef struct gattc_svc_cache {
|
||||
tBTA_GATT_SRVC_ID service_uuid;
|
||||
tBTA_GATTC_CACHE_ATTR *p_attr;
|
||||
tBTA_GATTC_CACHE_ATTR *p_last_attr;
|
||||
UINT16 s_handle;
|
||||
UINT16 e_handle;
|
||||
struct gattc_svc_cache *p_next;
|
||||
tBTA_GATTC_CACHE_ATTR *p_cur_char;
|
||||
// btla-specific ++
|
||||
} __attribute__((packed)) tBTA_GATTC_CACHE;
|
||||
// btla-specific --
|
||||
|
||||
typedef struct {
|
||||
tBT_UUID uuid;
|
||||
UINT16 s_handle;
|
||||
UINT16 e_handle;
|
||||
BOOLEAN is_primary;
|
||||
UINT8 srvc_inst_id;
|
||||
tBTA_GATT_CHAR_PROP property;
|
||||
} tBTA_GATTC_ATTR_REC;
|
||||
|
||||
|
||||
#define BTA_GATTC_MAX_CACHE_CHAR 40
|
||||
#define BTA_GATTC_ATTR_LIST_SIZE (BTA_GATTC_MAX_CACHE_CHAR * sizeof(tBTA_GATTC_ATTR_REC))
|
||||
|
||||
#ifndef BTA_GATTC_CACHE_SRVR_SIZE
|
||||
#define BTA_GATTC_CACHE_SRVR_SIZE 600
|
||||
#endif
|
||||
|
||||
enum {
|
||||
BTA_GATTC_IDLE_ST = 0, /* Idle */
|
||||
BTA_GATTC_W4_CONN_ST, /* Wait for connection - (optional) */
|
||||
BTA_GATTC_CONN_ST, /* connected state */
|
||||
BTA_GATTC_DISCOVER_ST /* discover is in progress */
|
||||
};
|
||||
typedef UINT8 tBTA_GATTC_STATE;
|
||||
|
||||
typedef struct {
|
||||
BOOLEAN in_use;
|
||||
BD_ADDR server_bda;
|
||||
BOOLEAN connected;
|
||||
|
||||
#define BTA_GATTC_SERV_IDLE 0
|
||||
#define BTA_GATTC_SERV_LOAD 1
|
||||
#define BTA_GATTC_SERV_SAVE 2
|
||||
#define BTA_GATTC_SERV_DISC 3
|
||||
#define BTA_GATTC_SERV_DISC_ACT 4
|
||||
|
||||
UINT8 state;
|
||||
|
||||
tBTA_GATTC_CACHE *p_srvc_cache;
|
||||
tBTA_GATTC_CACHE *p_cur_srvc;
|
||||
BUFFER_Q cache_buffer; /* buffer queue used for storing the cache data */
|
||||
UINT8 *p_free; /* starting point to next available byte */
|
||||
UINT16 free_byte; /* number of available bytes in server cache buffer */
|
||||
UINT8 update_count; /* indication received */
|
||||
UINT8 num_clcb; /* number of associated CLCB */
|
||||
|
||||
|
||||
tBTA_GATTC_ATTR_REC *p_srvc_list;
|
||||
UINT8 cur_srvc_idx;
|
||||
UINT8 cur_char_idx;
|
||||
UINT8 next_avail_idx;
|
||||
UINT8 total_srvc;
|
||||
UINT8 total_char;
|
||||
|
||||
UINT8 srvc_hdl_chg; /* service handle change indication pending */
|
||||
UINT16 attr_index; /* cahce NV saving/loading attribute index */
|
||||
|
||||
UINT16 mtu;
|
||||
} tBTA_GATTC_SERV;
|
||||
|
||||
#ifndef BTA_GATTC_NOTIF_REG_MAX
|
||||
#define BTA_GATTC_NOTIF_REG_MAX 15
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
BOOLEAN in_use;
|
||||
BD_ADDR remote_bda;
|
||||
tBTA_GATTC_CHAR_ID char_id;
|
||||
} tBTA_GATTC_NOTIF_REG;
|
||||
|
||||
typedef struct {
|
||||
tBTA_GATTC_CBACK *p_cback;
|
||||
BOOLEAN in_use;
|
||||
tBTA_GATTC_IF client_if; /* client interface with BTE stack for this application */
|
||||
UINT8 num_clcb; /* number of associated CLCB */
|
||||
BOOLEAN dereg_pending;
|
||||
tBT_UUID app_uuid;
|
||||
tBTA_GATTC_NOTIF_REG notif_reg[BTA_GATTC_NOTIF_REG_MAX];
|
||||
} tBTA_GATTC_RCB;
|
||||
|
||||
/* client channel is a mapping between a BTA client(cl_id) and a remote BD address */
|
||||
typedef struct {
|
||||
UINT16 bta_conn_id; /* client channel ID, unique for clcb */
|
||||
BD_ADDR bda;
|
||||
tBTA_TRANSPORT transport; /* channel transport */
|
||||
tBTA_GATTC_RCB *p_rcb; /* pointer to the registration CB */
|
||||
tBTA_GATTC_SERV *p_srcb; /* server cache CB */
|
||||
tBTA_GATTC_DATA *p_q_cmd; /* command in queue waiting for execution */
|
||||
|
||||
#define BTA_GATTC_NO_SCHEDULE 0
|
||||
#define BTA_GATTC_DISC_WAITING 0x01
|
||||
#define BTA_GATTC_REQ_WAITING 0x10
|
||||
|
||||
UINT8 auto_update; /* auto update is waiting */
|
||||
BOOLEAN disc_active;
|
||||
BOOLEAN in_use;
|
||||
tBTA_GATTC_STATE state;
|
||||
tBTA_GATT_STATUS status;
|
||||
UINT16 reason;
|
||||
} tBTA_GATTC_CLCB;
|
||||
|
||||
/* back ground connection tracking information */
|
||||
#if GATT_MAX_APPS <= 8
|
||||
typedef UINT8 tBTA_GATTC_CIF_MASK ;
|
||||
#elif GATT_MAX_APPS <= 16
|
||||
typedef UINT16 tBTA_GATTC_CIF_MASK;
|
||||
#elif GATT_MAX_APPS <= 32
|
||||
typedef UINT32 tBTA_GATTC_CIF_MASK;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
BOOLEAN in_use;
|
||||
BD_ADDR remote_bda;
|
||||
tBTA_GATTC_CIF_MASK cif_mask;
|
||||
tBTA_GATTC_CIF_MASK cif_adv_mask;
|
||||
|
||||
} tBTA_GATTC_BG_TCK;
|
||||
|
||||
typedef struct {
|
||||
BOOLEAN in_use;
|
||||
BD_ADDR remote_bda;
|
||||
} tBTA_GATTC_CONN;
|
||||
|
||||
enum {
|
||||
BTA_GATTC_STATE_DISABLED,
|
||||
BTA_GATTC_STATE_ENABLING,
|
||||
BTA_GATTC_STATE_ENABLED,
|
||||
BTA_GATTC_STATE_DISABLING
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
UINT8 state;
|
||||
|
||||
tBTA_GATTC_CONN conn_track[BTA_GATTC_CONN_MAX];
|
||||
tBTA_GATTC_BG_TCK bg_track[BTA_GATTC_KNOWN_SR_MAX];
|
||||
tBTA_GATTC_RCB cl_rcb[BTA_GATTC_CL_MAX];
|
||||
|
||||
tBTA_GATTC_CLCB clcb[BTA_GATTC_CLCB_MAX];
|
||||
tBTA_GATTC_SERV known_server[BTA_GATTC_KNOWN_SR_MAX];
|
||||
|
||||
tSDP_DISCOVERY_DB *p_sdp_db;
|
||||
UINT16 sdp_conn_id;
|
||||
} tBTA_GATTC_CB;
|
||||
|
||||
/*****************************************************************************
|
||||
** Global data
|
||||
*****************************************************************************/
|
||||
|
||||
/* GATTC control block */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
extern tBTA_GATTC_CB bta_gattc_cb;
|
||||
#else
|
||||
extern tBTA_GATTC_CB *bta_gattc_cb_ptr;
|
||||
#define bta_gattc_cb (*bta_gattc_cb_ptr)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
** Function prototypes
|
||||
*****************************************************************************/
|
||||
extern BOOLEAN bta_gattc_hdl_event(BT_HDR *p_msg);
|
||||
extern BOOLEAN bta_gattc_sm_execute(tBTA_GATTC_CLCB *p_clcb, UINT16 event, tBTA_GATTC_DATA *p_data);
|
||||
|
||||
/* function processed outside SM */
|
||||
extern void bta_gattc_disable(tBTA_GATTC_CB *p_cb);
|
||||
extern void bta_gattc_register(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_start_if(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_process_api_open (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
|
||||
extern void bta_gattc_process_api_open_cancel (tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
|
||||
extern void bta_gattc_deregister(tBTA_GATTC_CB *p_cb, tBTA_GATTC_RCB *p_clreg);
|
||||
extern void bta_gattc_process_enc_cmpl(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
|
||||
|
||||
/* function within state machine */
|
||||
extern void bta_gattc_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_open_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
|
||||
extern void bta_gattc_cancel_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_cancel_open_ok(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_cancel_open_error(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
|
||||
extern void bta_gattc_conn(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
|
||||
extern void bta_gattc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_close_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_disc_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
|
||||
extern void bta_gattc_start_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_disc_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_read(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_write(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_q_cmd(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_search(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_fail(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_confirm(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_execute(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_read_multi(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_ci_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_ci_load(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_ci_close(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_ci_save(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_cache_open(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_ignore_op_cmpl(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
extern void bta_gattc_restart_discover(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_msg);
|
||||
extern void bta_gattc_init_bk_conn(tBTA_GATTC_API_OPEN *p_data, tBTA_GATTC_RCB *p_clreg);
|
||||
extern void bta_gattc_cancel_bk_conn(tBTA_GATTC_API_CANCEL_OPEN *p_data);
|
||||
extern void bta_gattc_send_open_cback( tBTA_GATTC_RCB *p_clreg, tBTA_GATT_STATUS status,
|
||||
BD_ADDR remote_bda, UINT16 conn_id, tBTA_TRANSPORT transport, UINT16 mtu);
|
||||
extern void bta_gattc_process_api_refresh(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
|
||||
extern void bta_gattc_cfg_mtu(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
#if BLE_INCLUDED == TRUE
|
||||
extern void bta_gattc_listen(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
|
||||
extern void bta_gattc_broadcast(tBTA_GATTC_CB *p_cb, tBTA_GATTC_DATA *p_msg);
|
||||
#endif
|
||||
/* utility functions */
|
||||
extern tBTA_GATTC_CLCB *bta_gattc_find_clcb_by_cif (UINT8 client_if, BD_ADDR remote_bda, tBTA_TRANSPORT transport);
|
||||
extern tBTA_GATTC_CLCB *bta_gattc_find_clcb_by_conn_id (UINT16 conn_id);
|
||||
extern tBTA_GATTC_CLCB *bta_gattc_clcb_alloc(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_TRANSPORT transport);
|
||||
extern void bta_gattc_clcb_dealloc(tBTA_GATTC_CLCB *p_clcb);
|
||||
extern tBTA_GATTC_CLCB *bta_gattc_find_alloc_clcb(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_TRANSPORT transport);
|
||||
extern tBTA_GATTC_RCB *bta_gattc_cl_get_regcb(UINT8 client_if);
|
||||
extern tBTA_GATTC_SERV *bta_gattc_find_srcb(BD_ADDR bda);
|
||||
extern tBTA_GATTC_SERV *bta_gattc_srcb_alloc(BD_ADDR bda);
|
||||
extern tBTA_GATTC_SERV *bta_gattc_find_scb_by_cid (UINT16 conn_id);
|
||||
extern tBTA_GATTC_CLCB *bta_gattc_find_int_conn_clcb(tBTA_GATTC_DATA *p_msg);
|
||||
extern tBTA_GATTC_CLCB *bta_gattc_find_int_disconn_clcb(tBTA_GATTC_DATA *p_msg);
|
||||
|
||||
extern BOOLEAN bta_gattc_enqueue(tBTA_GATTC_CLCB *p_clcb, tBTA_GATTC_DATA *p_data);
|
||||
|
||||
extern UINT16 bta_gattc_id2handle(tBTA_GATTC_SERV *p_srcb, tBTA_GATT_SRVC_ID *p_service_id, tBTA_GATT_ID *p_char_id, tBTA_GATT_ID *p_descr_uuid);
|
||||
extern BOOLEAN bta_gattc_handle2id(tBTA_GATTC_SERV *p_srcb, UINT16 handle, tBTA_GATT_SRVC_ID *service_id, tBTA_GATT_ID *char_id, tBTA_GATT_ID *p_type);
|
||||
extern BOOLEAN bta_gattc_uuid_compare (tBT_UUID *p_src, tBT_UUID *p_tar, BOOLEAN is_precise);
|
||||
extern void bta_gattc_pack_attr_uuid(tBTA_GATTC_CACHE_ATTR *p_attr, tBT_UUID *p_uuid);
|
||||
extern BOOLEAN bta_gattc_check_notif_registry(tBTA_GATTC_RCB *p_clreg, tBTA_GATTC_SERV *p_srcb, tBTA_GATTC_NOTIFY *p_notify);
|
||||
extern tBTA_GATT_STATUS bta_gattc_pack_read_cb_data(tBTA_GATTC_SERV *p_srcb, tBT_UUID *p_descr_uuid, tGATT_VALUE *p_attr, tBTA_GATT_READ_VAL *p_value);
|
||||
extern BOOLEAN bta_gattc_mark_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR_PTR remote_bda, BOOLEAN add, BOOLEAN is_listen);
|
||||
extern BOOLEAN bta_gattc_check_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR remote_bda, UINT8 role);
|
||||
extern UINT8 bta_gattc_num_reg_app(void);
|
||||
extern void bta_gattc_clear_notif_registration(UINT16 conn_id);
|
||||
extern tBTA_GATTC_SERV *bta_gattc_find_srvr_cache(BD_ADDR bda);
|
||||
extern BOOLEAN bta_gattc_charid_compare(tBTA_GATTC_CHAR_ID *p_src, tBTA_GATTC_CHAR_ID *p_tar);
|
||||
extern BOOLEAN bta_gattc_srvcid_compare(tBTA_GATT_SRVC_ID *p_src, tBTA_GATT_SRVC_ID *p_tar);
|
||||
extern void bta_gattc_cpygattid(tBTA_GATT_ID *p_des, tBTA_GATT_ID *p_src);
|
||||
|
||||
/* discovery functions */
|
||||
extern void bta_gattc_disc_res_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_DISC_RES *p_data);
|
||||
extern void bta_gattc_disc_cmpl_cback (UINT16 conn_id, tGATT_DISC_TYPE disc_type, tGATT_STATUS status);
|
||||
extern tBTA_GATT_STATUS bta_gattc_discover_procedure(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb, UINT8 disc_type);
|
||||
extern tBTA_GATT_STATUS bta_gattc_discover_pri_service(UINT16 conn_id, tBTA_GATTC_SERV *p_server_cb, UINT8 disc_type);
|
||||
extern void bta_gattc_search_service(tBTA_GATTC_CLCB *p_clcb, tBT_UUID *p_uuid);
|
||||
extern tBTA_GATT_STATUS bta_gattc_query_cache(UINT16 conn_id, UINT8 query_type, tBTA_GATT_SRVC_ID *p_srvc_id,
|
||||
tBTA_GATT_ID *p_start_rec, tBT_UUID *p_uuid_cond,
|
||||
tBTA_GATT_ID *p_output, void *p_param);
|
||||
extern tBTA_GATT_STATUS bta_gattc_init_cache(tBTA_GATTC_SERV *p_srvc_cb);
|
||||
extern void bta_gattc_rebuild_cache(tBTA_GATTC_SERV *p_srcv, UINT16 num_attr, tBTA_GATTC_NV_ATTR *p_attr, UINT16 attr_index);
|
||||
extern BOOLEAN bta_gattc_cache_save(tBTA_GATTC_SERV *p_srvc_cb, UINT16 conn_id);
|
||||
|
||||
|
||||
extern tBTA_GATTC_CONN *bta_gattc_conn_alloc(BD_ADDR remote_bda);
|
||||
extern tBTA_GATTC_CONN *bta_gattc_conn_find(BD_ADDR remote_bda);
|
||||
extern tBTA_GATTC_CONN *bta_gattc_conn_find_alloc(BD_ADDR remote_bda);
|
||||
extern BOOLEAN bta_gattc_conn_dealloc(BD_ADDR remote_bda);
|
||||
|
||||
#endif /* BTA_GATTC_INT_H */
|
||||
81
components/bt/bluedroid/bta/include/bta_gatts_co.h
Normal file
81
components/bt/bluedroid/bta/include/bta_gatts_co.h
Normal file
@@ -0,0 +1,81 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2010-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the interface file for BTA GATT server call-out functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_GATTS_CO_H
|
||||
#define BTA_GATTS_CO_H
|
||||
|
||||
#include "bta_gatt_api.h"
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_co_update_handle_range
|
||||
**
|
||||
** Description This callout function is executed by GATTS when a GATT server
|
||||
** handle range ios to be added or removed.
|
||||
**
|
||||
** Parameter is_add: true is to add a handle range; otherwise is to delete.
|
||||
** p_hndl_range: handle range.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_gatts_co_update_handle_range(BOOLEAN is_add, tBTA_GATTS_HNDL_RANGE *p_hndl_range);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_co_srv_chg
|
||||
**
|
||||
** Description This call-out is to read/write/remove service change related
|
||||
** informaiton. The request consists of the cmd and p_req and the
|
||||
** response is returned in p_rsp
|
||||
**
|
||||
** Parameter cmd - request command
|
||||
** p_req - request paramters
|
||||
** p_rsp - response data for the request
|
||||
**
|
||||
** Returns TRUE - if the request is processed successfully and
|
||||
** the response is returned in p_rsp.
|
||||
** FASLE - if the request can not be processed
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern BOOLEAN bta_gatts_co_srv_chg(tBTA_GATTS_SRV_CHG_CMD cmd,
|
||||
tBTA_GATTS_SRV_CHG_REQ *p_req,
|
||||
tBTA_GATTS_SRV_CHG_RSP *p_rsp);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gatts_co_load_handle_range
|
||||
**
|
||||
** Description This callout function is executed by GATTS when a GATT server
|
||||
** handle range is requested to be loaded from NV.
|
||||
**
|
||||
** Parameter
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern BOOLEAN bta_gatts_co_load_handle_range(UINT8 index,
|
||||
tBTA_GATTS_HNDL_RANGE *p_handle);
|
||||
|
||||
|
||||
#endif /* BTA_GATTS_CO_H */
|
||||
244
components/bt/bluedroid/bta/include/bta_gatts_int.h
Normal file
244
components/bt/bluedroid/bta/include/bta_gatts_int.h
Normal file
@@ -0,0 +1,244 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the private file for the BTA GATT server.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_GATTS_INT_H
|
||||
#define BTA_GATTS_INT_H
|
||||
|
||||
#include "bt_target.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_gatt_api.h"
|
||||
#include "gatt_api.h"
|
||||
|
||||
#include "gki.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and data types
|
||||
*****************************************************************************/
|
||||
enum {
|
||||
BTA_GATTS_API_REG_EVT = BTA_SYS_EVT_START(BTA_ID_GATTS),
|
||||
BTA_GATTS_INT_START_IF_EVT,
|
||||
BTA_GATTS_API_DEREG_EVT,
|
||||
BTA_GATTS_API_CREATE_SRVC_EVT,
|
||||
BTA_GATTS_API_INDICATION_EVT,
|
||||
|
||||
BTA_GATTS_API_ADD_INCL_SRVC_EVT,
|
||||
BTA_GATTS_API_ADD_CHAR_EVT,
|
||||
BTA_GATTS_API_ADD_DESCR_EVT,
|
||||
BTA_GATTS_API_DEL_SRVC_EVT,
|
||||
BTA_GATTS_API_START_SRVC_EVT,
|
||||
BTA_GATTS_API_STOP_SRVC_EVT,
|
||||
BTA_GATTS_API_RSP_EVT,
|
||||
BTA_GATTS_API_OPEN_EVT,
|
||||
BTA_GATTS_API_CANCEL_OPEN_EVT,
|
||||
BTA_GATTS_API_CLOSE_EVT,
|
||||
BTA_GATTS_API_LISTEN_EVT,
|
||||
BTA_GATTS_API_DISABLE_EVT
|
||||
};
|
||||
typedef UINT16 tBTA_GATTS_INT_EVT;
|
||||
|
||||
/* max number of application allowed on device */
|
||||
#define BTA_GATTS_MAX_APP_NUM GATT_MAX_SR_PROFILES
|
||||
|
||||
/* max number of services allowed in the device */
|
||||
#define BTA_GATTS_MAX_SRVC_NUM GATT_MAX_SR_PROFILES
|
||||
|
||||
/* internal strucutre for GATTC register API */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBT_UUID app_uuid;
|
||||
tBTA_GATTS_CBACK *p_cback;
|
||||
} tBTA_GATTS_API_REG;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATTS_IF server_if;
|
||||
} tBTA_GATTS_INT_START_IF;
|
||||
|
||||
typedef tBTA_GATTS_INT_START_IF tBTA_GATTS_API_DEREG;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATTS_IF server_if;
|
||||
tBT_UUID service_uuid;
|
||||
UINT16 num_handle;
|
||||
UINT8 inst;
|
||||
BOOLEAN is_pri;
|
||||
|
||||
} tBTA_GATTS_API_CREATE_SRVC;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBT_UUID char_uuid;
|
||||
tBTA_GATT_PERM perm;
|
||||
tBTA_GATT_CHAR_PROP property;
|
||||
|
||||
} tBTA_GATTS_API_ADD_CHAR;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT16 included_service_id;
|
||||
|
||||
} tBTA_GATTS_API_ADD_INCL_SRVC;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBT_UUID descr_uuid;
|
||||
tBTA_GATT_PERM perm;
|
||||
} tBTA_GATTS_API_ADD_DESCR;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT16 attr_id;
|
||||
UINT16 len;
|
||||
BOOLEAN need_confirm;
|
||||
UINT8 value[BTA_GATT_MAX_ATTR_LEN];
|
||||
} tBTA_GATTS_API_INDICATION;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT32 trans_id;
|
||||
tBTA_GATT_STATUS status;
|
||||
tBTA_GATTS_RSP *p_rsp;
|
||||
} tBTA_GATTS_API_RSP;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATT_TRANSPORT transport;
|
||||
} tBTA_GATTS_API_START;
|
||||
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR remote_bda;
|
||||
tBTA_GATTS_IF server_if;
|
||||
BOOLEAN is_direct;
|
||||
tBTA_GATT_TRANSPORT transport;
|
||||
|
||||
} tBTA_GATTS_API_OPEN;
|
||||
|
||||
typedef tBTA_GATTS_API_OPEN tBTA_GATTS_API_CANCEL_OPEN;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR_PTR remote_bda;
|
||||
tBTA_GATTS_IF server_if;
|
||||
BOOLEAN start;
|
||||
} tBTA_GATTS_API_LISTEN;
|
||||
|
||||
typedef union {
|
||||
BT_HDR hdr;
|
||||
tBTA_GATTS_API_REG api_reg;
|
||||
tBTA_GATTS_API_DEREG api_dereg;
|
||||
tBTA_GATTS_API_CREATE_SRVC api_create_svc;
|
||||
tBTA_GATTS_API_ADD_INCL_SRVC api_add_incl_srvc;
|
||||
tBTA_GATTS_API_ADD_CHAR api_add_char;
|
||||
tBTA_GATTS_API_ADD_DESCR api_add_char_descr;
|
||||
tBTA_GATTS_API_START api_start;
|
||||
tBTA_GATTS_API_INDICATION api_indicate;
|
||||
tBTA_GATTS_API_RSP api_rsp;
|
||||
tBTA_GATTS_API_OPEN api_open;
|
||||
tBTA_GATTS_API_CANCEL_OPEN api_cancel_open;
|
||||
|
||||
tBTA_GATTS_INT_START_IF int_start_if;
|
||||
/* if peripheral role is supported */
|
||||
tBTA_GATTS_API_LISTEN api_listen;
|
||||
} tBTA_GATTS_DATA;
|
||||
|
||||
/* application registration control block */
|
||||
typedef struct {
|
||||
BOOLEAN in_use;
|
||||
tBT_UUID app_uuid;
|
||||
tBTA_GATTS_CBACK *p_cback;
|
||||
tBTA_GATTS_IF gatt_if;
|
||||
} tBTA_GATTS_RCB;
|
||||
|
||||
/* service registration control block */
|
||||
typedef struct {
|
||||
tBT_UUID service_uuid; /* service UUID */
|
||||
UINT16 service_id; /* service handle */
|
||||
UINT8 inst_num; /* instance ID */
|
||||
UINT8 rcb_idx;
|
||||
UINT8 idx; /* self index of serviec CB */
|
||||
BOOLEAN in_use;
|
||||
|
||||
} tBTA_GATTS_SRVC_CB;
|
||||
|
||||
|
||||
/* GATT server control block */
|
||||
typedef struct {
|
||||
BOOLEAN enabled;
|
||||
tBTA_GATTS_RCB rcb[BTA_GATTS_MAX_APP_NUM];
|
||||
tBTA_GATTS_SRVC_CB srvc_cb[BTA_GATTS_MAX_SRVC_NUM];
|
||||
} tBTA_GATTS_CB;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Global data
|
||||
*****************************************************************************/
|
||||
|
||||
/* GATTC control block */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
extern tBTA_GATTS_CB bta_gatts_cb;
|
||||
#else
|
||||
extern tBTA_GATTS_CB *bta_gatts_cb_ptr;
|
||||
#define bta_gatts_cb (*bta_gatts_cb_ptr)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
** Function prototypes
|
||||
*****************************************************************************/
|
||||
extern BOOLEAN bta_gatts_hdl_event(BT_HDR *p_msg);
|
||||
|
||||
extern void bta_gatts_api_disable(tBTA_GATTS_CB *p_cb);
|
||||
extern void bta_gatts_api_enable(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_data);
|
||||
extern void bta_gatts_register(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_start_if(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_deregister(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_create_srvc(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_add_include_srvc(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_add_char(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_add_char_descr(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_delete_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_start_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_stop_service(tBTA_GATTS_SRVC_CB *p_srvc_cb, tBTA_GATTS_DATA *p_msg);
|
||||
|
||||
extern void bta_gatts_send_rsp(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
|
||||
|
||||
extern void bta_gatts_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_cancel_open (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_close (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
extern void bta_gatts_listen(tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg);
|
||||
|
||||
extern BOOLEAN bta_gatts_uuid_compare(tBT_UUID tar, tBT_UUID src);
|
||||
extern tBTA_GATTS_RCB *bta_gatts_find_app_rcb_by_app_if(tBTA_GATTS_IF server_if);
|
||||
extern UINT8 bta_gatts_find_app_rcb_idx_by_app_if(tBTA_GATTS_CB *p_cb, tBTA_GATTS_IF server_if);
|
||||
extern UINT8 bta_gatts_alloc_srvc_cb(tBTA_GATTS_CB *p_cb, UINT8 rcb_idx);
|
||||
extern tBTA_GATTS_SRVC_CB *bta_gatts_find_srvc_cb_by_srvc_id(tBTA_GATTS_CB *p_cb, UINT16 service_id);
|
||||
extern tBTA_GATTS_SRVC_CB *bta_gatts_find_srvc_cb_by_attr_id(tBTA_GATTS_CB *p_cb, UINT16 attr_id);
|
||||
|
||||
|
||||
#endif /* BTA_GATTS_INT_H */
|
||||
|
||||
541
components/bt/bluedroid/bta/include/bta_hh_api.h
Normal file
541
components/bt/bluedroid/bta/include/bta_hh_api.h
Normal file
@@ -0,0 +1,541 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_HH_API_H
|
||||
#define BTA_HH_API_H
|
||||
|
||||
#include "bta_api.h"
|
||||
#include "hidh_api.h"
|
||||
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
#include "gatt_api.h"
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and Type Definitions
|
||||
*****************************************************************************/
|
||||
#ifndef BTA_HH_DEBUG
|
||||
#define BTA_HH_DEBUG TRUE
|
||||
#endif
|
||||
|
||||
#ifndef BTA_HH_SSR_MAX_LATENCY_DEF
|
||||
#define BTA_HH_SSR_MAX_LATENCY_DEF 800 /* 500 ms*/
|
||||
#endif
|
||||
|
||||
#ifndef BTA_HH_SSR_MIN_TOUT_DEF
|
||||
#define BTA_HH_SSR_MIN_TOUT_DEF 2
|
||||
#endif
|
||||
|
||||
/* BTA HID Host callback events */
|
||||
#define BTA_HH_ENABLE_EVT 0 /* HH enabled */
|
||||
#define BTA_HH_DISABLE_EVT 1 /* HH disabled */
|
||||
#define BTA_HH_OPEN_EVT 2 /* connection opened */
|
||||
#define BTA_HH_CLOSE_EVT 3 /* connection closed */
|
||||
#define BTA_HH_GET_RPT_EVT 4 /* BTA_HhGetReport callback */
|
||||
#define BTA_HH_SET_RPT_EVT 5 /* BTA_HhSetReport callback */
|
||||
#define BTA_HH_GET_PROTO_EVT 6 /* BTA_GetProtoMode callback */
|
||||
#define BTA_HH_SET_PROTO_EVT 7 /* BTA_HhSetProtoMode callback */
|
||||
#define BTA_HH_GET_IDLE_EVT 8 /* BTA_HhGetIdle comes callback */
|
||||
#define BTA_HH_SET_IDLE_EVT 9 /* BTA_HhSetIdle finish callback */
|
||||
#define BTA_HH_GET_DSCP_EVT 10 /* Get report descriptor */
|
||||
#define BTA_HH_ADD_DEV_EVT 11 /* Add Device callback */
|
||||
#define BTA_HH_RMV_DEV_EVT 12 /* remove device finished */
|
||||
#define BTA_HH_VC_UNPLUG_EVT 13 /* virtually unplugged */
|
||||
#define BTA_HH_DATA_EVT 15
|
||||
#define BTA_HH_API_ERR_EVT 16 /* API error is caught */
|
||||
#define BTA_HH_UPDATE_SCPP_EVT 17 /* update scan paramter complete */
|
||||
|
||||
typedef UINT16 tBTA_HH_EVT;
|
||||
|
||||
/* application ID(none-zero) for each type of device */
|
||||
#define BTA_HH_APP_ID_MI 1
|
||||
#define BTA_HH_APP_ID_KB 2
|
||||
#define BTA_HH_APP_ID_RMC 3
|
||||
#define BTA_HH_APP_ID_3DSG 4
|
||||
#define BTA_HH_APP_ID_JOY 5
|
||||
#define BTA_HH_APP_ID_GPAD 6
|
||||
#define BTA_HH_APP_ID_LE 0xff
|
||||
|
||||
/* defined the minimum offset */
|
||||
#define BTA_HH_MIN_OFFSET L2CAP_MIN_OFFSET+1
|
||||
|
||||
/* HID_HOST_MAX_DEVICES can not exceed 15 for th design of BTA HH */
|
||||
#define BTA_HH_IDX_INVALID 0xff
|
||||
#define BTA_HH_MAX_KNOWN HID_HOST_MAX_DEVICES
|
||||
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
/* GATT_MAX_PHY_CHANNEL can not exceed 14 for the design of BTA HH */
|
||||
#define BTA_HH_LE_MAX_KNOWN GATT_MAX_PHY_CHANNEL
|
||||
#define BTA_HH_MAX_DEVICE (HID_HOST_MAX_DEVICES + GATT_MAX_PHY_CHANNEL)
|
||||
#else
|
||||
#define BTA_HH_MAX_DEVICE HID_HOST_MAX_DEVICES
|
||||
#endif
|
||||
/* invalid device handle */
|
||||
#define BTA_HH_INVALID_HANDLE 0xff
|
||||
|
||||
/* type of protocol mode */
|
||||
#define BTA_HH_PROTO_RPT_MODE (0x00)
|
||||
#define BTA_HH_PROTO_BOOT_MODE (0x01)
|
||||
#define BTA_HH_PROTO_UNKNOWN (0xff)
|
||||
typedef UINT8 tBTA_HH_PROTO_MODE;
|
||||
|
||||
enum {
|
||||
BTA_HH_KEYBD_RPT_ID = 1,
|
||||
BTA_HH_MOUSE_RPT_ID
|
||||
};
|
||||
typedef UINT8 tBTA_HH_BOOT_RPT_ID;
|
||||
|
||||
/* type of devices, bit mask */
|
||||
#define BTA_HH_DEVT_UNKNOWN 0x00
|
||||
#define BTA_HH_DEVT_JOS 0x01 /* joy stick */
|
||||
#define BTA_HH_DEVT_GPD 0x02 /* game pad */
|
||||
#define BTA_HH_DEVT_RMC 0x03 /* remote control */
|
||||
#define BTA_HH_DEVT_SED 0x04 /* sensing device */
|
||||
#define BTA_HH_DEVT_DGT 0x05 /* Digitizer tablet */
|
||||
#define BTA_HH_DEVT_CDR 0x06 /* card reader */
|
||||
#define BTA_HH_DEVT_KBD 0x10 /* keyboard */
|
||||
#define BTA_HH_DEVT_MIC 0x20 /* pointing device */
|
||||
#define BTA_HH_DEVT_COM 0x30 /* Combo keyboard/pointing */
|
||||
#define BTA_HH_DEVT_OTHER 0x80
|
||||
typedef UINT8 tBTA_HH_DEVT;
|
||||
|
||||
enum {
|
||||
BTA_HH_OK,
|
||||
BTA_HH_HS_HID_NOT_READY, /* handshake error : device not ready */
|
||||
BTA_HH_HS_INVALID_RPT_ID, /* handshake error : invalid report ID */
|
||||
BTA_HH_HS_TRANS_NOT_SPT, /* handshake error : transaction not spt */
|
||||
BTA_HH_HS_INVALID_PARAM, /* handshake error : invalid paremter */
|
||||
BTA_HH_HS_ERROR, /* handshake error : unspecified HS error */
|
||||
BTA_HH_ERR, /* general BTA HH error */
|
||||
BTA_HH_ERR_SDP, /* SDP error */
|
||||
BTA_HH_ERR_PROTO, /* SET_Protocol error,
|
||||
only used in BTA_HH_OPEN_EVT callback */
|
||||
|
||||
BTA_HH_ERR_DB_FULL, /* device database full error, used in
|
||||
BTA_HH_OPEN_EVT/BTA_HH_ADD_DEV_EVT */
|
||||
BTA_HH_ERR_TOD_UNSPT, /* type of device not supported */
|
||||
BTA_HH_ERR_NO_RES, /* out of system resources */
|
||||
BTA_HH_ERR_AUTH_FAILED, /* authentication fail */
|
||||
BTA_HH_ERR_HDL,
|
||||
BTA_HH_ERR_SEC
|
||||
};
|
||||
typedef UINT8 tBTA_HH_STATUS;
|
||||
|
||||
|
||||
#define BTA_HH_VIRTUAL_CABLE HID_VIRTUAL_CABLE
|
||||
#define BTA_HH_NORMALLY_CONNECTABLE HID_NORMALLY_CONNECTABLE
|
||||
#define BTA_HH_RECONN_INIT HID_RECONN_INIT
|
||||
#define BTA_HH_SDP_DISABLE HID_SDP_DISABLE
|
||||
#define BTA_HH_BATTERY_POWER HID_BATTERY_POWER
|
||||
#define BTA_HH_REMOTE_WAKE HID_REMOTE_WAKE
|
||||
#define BTA_HH_SUP_TOUT_AVLBL HID_SUP_TOUT_AVLBL
|
||||
#define BTA_HH_SEC_REQUIRED HID_SEC_REQUIRED
|
||||
typedef UINT16 tBTA_HH_ATTR_MASK;
|
||||
|
||||
/* supported type of device and corresponding application ID */
|
||||
typedef struct {
|
||||
tBTA_HH_DEVT tod; /* type of device */
|
||||
UINT8 app_id; /* corresponding application ID */
|
||||
} tBTA_HH_SPT_TOD;
|
||||
|
||||
/* configuration struct */
|
||||
typedef struct {
|
||||
UINT8 max_devt_spt; /* max number of types of devices spt */
|
||||
tBTA_HH_SPT_TOD *p_devt_list; /* supported types of device list */
|
||||
UINT16 sdp_db_size;
|
||||
} tBTA_HH_CFG;
|
||||
|
||||
enum {
|
||||
BTA_HH_RPTT_RESRV, /* reserved */
|
||||
BTA_HH_RPTT_INPUT, /* input report */
|
||||
BTA_HH_RPTT_OUTPUT, /* output report */
|
||||
BTA_HH_RPTT_FEATURE /* feature report */
|
||||
};
|
||||
typedef UINT8 tBTA_HH_RPT_TYPE;
|
||||
|
||||
/* HID_CONTROL operation code used in BTA_HhSendCtrl()
|
||||
*/
|
||||
enum {
|
||||
BTA_HH_CTRL_NOP = 0 + HID_PAR_CONTROL_NOP ,/* mapping from BTE */
|
||||
BTA_HH_CTRL_HARD_RESET, /* hard reset */
|
||||
BTA_HH_CTRL_SOFT_RESET, /* soft reset */
|
||||
BTA_HH_CTRL_SUSPEND, /* enter suspend */
|
||||
BTA_HH_CTRL_EXIT_SUSPEND, /* exit suspend */
|
||||
BTA_HH_CTRL_VIRTUAL_CABLE_UNPLUG /* virtual unplug */
|
||||
};
|
||||
typedef UINT8 tBTA_HH_TRANS_CTRL_TYPE;
|
||||
|
||||
typedef tHID_DEV_DSCP_INFO tBTA_HH_DEV_DESCR;
|
||||
|
||||
#define BTA_HH_SSR_PARAM_INVALID HID_SSR_PARAM_INVALID
|
||||
|
||||
/* id DI is not existing in remote device, vendor_id in tBTA_HH_DEV_DSCP_INFO will be set to 0xffff */
|
||||
#define BTA_HH_VENDOR_ID_INVALID 0xffff
|
||||
|
||||
|
||||
/* report descriptor information */
|
||||
typedef struct {
|
||||
UINT16 vendor_id; /* vendor ID */
|
||||
UINT16 product_id; /* product ID */
|
||||
UINT16 version; /* version */
|
||||
UINT16 ssr_max_latency; /* SSR max latency, BTA_HH_SSR_PARAM_INVALID if unknown */
|
||||
UINT16 ssr_min_tout; /* SSR min timeout, BTA_HH_SSR_PARAM_INVALID if unknown */
|
||||
UINT8 ctry_code; /*Country Code.*/
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
#define BTA_HH_LE_REMOTE_WAKE 0x01
|
||||
#define BTA_HH_LE_NORMAL_CONN 0x02
|
||||
|
||||
UINT8 flag;
|
||||
#endif
|
||||
tBTA_HH_DEV_DESCR descriptor;
|
||||
} tBTA_HH_DEV_DSCP_INFO;
|
||||
|
||||
/* callback event data for BTA_HH_OPEN_EVT */
|
||||
typedef struct {
|
||||
BD_ADDR bda; /* HID device bd address */
|
||||
tBTA_HH_STATUS status; /* operation status */
|
||||
UINT8 handle; /* device handle */
|
||||
#if (defined BTA_HH_LE_INCLUDED && BTA_HH_LE_INCLUDED == TRUE)
|
||||
BOOLEAN le_hid; /* is LE devices? */
|
||||
BOOLEAN scps_supported; /* scan parameter service supported */
|
||||
#endif
|
||||
|
||||
} tBTA_HH_CONN;
|
||||
|
||||
typedef tBTA_HH_CONN tBTA_HH_DEV_INFO;
|
||||
|
||||
/* callback event data */
|
||||
typedef struct {
|
||||
tBTA_HH_STATUS status; /* operation status */
|
||||
UINT8 handle; /* device handle */
|
||||
} tBTA_HH_CBDATA;
|
||||
|
||||
enum {
|
||||
BTA_HH_MOD_CTRL_KEY,
|
||||
BTA_HH_MOD_SHFT_KEY,
|
||||
BTA_HH_MOD_ALT_KEY,
|
||||
BTA_HH_MOD_GUI_KEY,
|
||||
BTA_HH_MOD_MAX_KEY
|
||||
};
|
||||
|
||||
/* parsed boot mode keyboard report */
|
||||
typedef struct {
|
||||
UINT8 this_char[6]; /* virtual key code */
|
||||
BOOLEAN mod_key[BTA_HH_MOD_MAX_KEY];
|
||||
/* ctrl, shift, Alt, GUI */
|
||||
/* modifier key: is Shift key pressed */
|
||||
/* modifier key: is Ctrl key pressed */
|
||||
/* modifier key: is Alt key pressed */
|
||||
/* modifier key: GUI up/down */
|
||||
BOOLEAN caps_lock; /* is caps locked */
|
||||
BOOLEAN num_lock; /* is Num key pressed */
|
||||
} tBTA_HH_KEYBD_RPT;
|
||||
|
||||
/* parsed boot mode mouse report */
|
||||
typedef struct {
|
||||
UINT8 mouse_button; /* mouse button is clicked */
|
||||
INT8 delta_x; /* displacement x */
|
||||
INT8 delta_y; /* displacement y */
|
||||
} tBTA_HH_MICE_RPT;
|
||||
|
||||
/* parsed Boot report */
|
||||
typedef struct {
|
||||
tBTA_HH_BOOT_RPT_ID dev_type; /* type of device report */
|
||||
union {
|
||||
tBTA_HH_KEYBD_RPT keybd_rpt; /* keyboard report */
|
||||
tBTA_HH_MICE_RPT mice_rpt; /* mouse report */
|
||||
} data_rpt;
|
||||
} tBTA_HH_BOOT_RPT;
|
||||
|
||||
/* handshake data */
|
||||
typedef struct {
|
||||
tBTA_HH_STATUS status; /* handshake status */
|
||||
UINT8 handle; /* device handle */
|
||||
union {
|
||||
tBTA_HH_PROTO_MODE proto_mode; /* GET_PROTO_EVT :protocol mode */
|
||||
BT_HDR *p_rpt_data; /* GET_RPT_EVT : report data */
|
||||
UINT8 idle_rate; /* GET_IDLE_EVT : idle rate */
|
||||
} rsp_data;
|
||||
|
||||
} tBTA_HH_HSDATA;
|
||||
|
||||
/* union of data associated with HD callback */
|
||||
typedef union {
|
||||
tBTA_HH_DEV_INFO dev_info; /* BTA_HH_ADD_DEV_EVT, BTA_HH_RMV_DEV_EVT */
|
||||
tBTA_HH_CONN conn; /* BTA_HH_OPEN_EVT */
|
||||
tBTA_HH_CBDATA dev_status; /* BTA_HH_CLOSE_EVT,
|
||||
BTA_HH_SET_PROTO_EVT
|
||||
BTA_HH_SET_RPT_EVT
|
||||
BTA_HH_SET_IDLE_EVT
|
||||
BTA_HH_UPDATE_SCPP_EVT */
|
||||
|
||||
tBTA_HH_STATUS status; /* BTA_HH_ENABLE_EVT */
|
||||
tBTA_HH_DEV_DSCP_INFO dscp_info; /* BTA_HH_GET_DSCP_EVT */
|
||||
tBTA_HH_HSDATA hs_data; /* GET_ transaction callback
|
||||
BTA_HH_GET_RPT_EVT
|
||||
BTA_HH_GET_PROTO_EVT
|
||||
BTA_HH_GET_IDLE_EVT */
|
||||
} tBTA_HH;
|
||||
|
||||
/* BTA HH callback function */
|
||||
typedef void (tBTA_HH_CBACK) (tBTA_HH_EVT event, tBTA_HH *p_data);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** External Function Declarations
|
||||
*****************************************************************************/
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhRegister
|
||||
**
|
||||
** Description This function enable HID host and registers HID-Host with
|
||||
** lower layers.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhEnable(tBTA_SEC sec_mask, tBTA_HH_CBACK *p_cback);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhDeregister
|
||||
**
|
||||
** Description This function is called when the host is about power down.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhDisable(void);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhOpen
|
||||
**
|
||||
** Description This function is called to start an inquiry and read SDP
|
||||
** record of responding devices; connect to a device if only
|
||||
** one active HID device is found.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhOpen (BD_ADDR dev_bda, tBTA_HH_PROTO_MODE mode,
|
||||
tBTA_SEC sec_mask);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhClose
|
||||
**
|
||||
** Description This function disconnects the device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhClose(UINT8 dev_handle);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSetProtoMode
|
||||
**
|
||||
** Description This function set the protocol mode at specified HID handle
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhSetProtoMode(UINT8 handle, tBTA_HH_PROTO_MODE t_type);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetProtoMode
|
||||
**
|
||||
** Description This function get the protocol mode of a specified HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhGetProtoMode(UINT8 dev_handle);
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSetReport
|
||||
**
|
||||
** Description send SET_REPORT to device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhSetReport(UINT8 dev_handle, tBTA_HH_RPT_TYPE r_type,
|
||||
BT_HDR *p_data);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetReport
|
||||
**
|
||||
** Description Send a GET_REPORT to HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhGetReport(UINT8 dev_handle, tBTA_HH_RPT_TYPE r_type,
|
||||
UINT8 rpt_id, UINT16 buf_size);
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSetIdle
|
||||
**
|
||||
** Description send SET_IDLE to device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhSetIdle(UINT8 dev_handle, UINT16 idle_rate);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetIdle
|
||||
**
|
||||
** Description Send a GET_IDLE to HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhGetIdle(UINT8 dev_handle);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSendCtrl
|
||||
**
|
||||
** Description Send HID_CONTROL request to a HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhSendCtrl(UINT8 dev_handle,
|
||||
tBTA_HH_TRANS_CTRL_TYPE c_type);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSetIdle
|
||||
**
|
||||
** Description send SET_IDLE to device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhSetIdle(UINT8 dev_handle, UINT16 idle_rate);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetIdle
|
||||
**
|
||||
** Description Send a GET_IDLE from HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhGetIdle(UINT8 dev_handle);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhSendData
|
||||
**
|
||||
** Description Send DATA transaction to a HID device.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhSendData(UINT8 dev_handle, BD_ADDR dev_bda, BT_HDR *p_buf);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhGetDscpInfo
|
||||
**
|
||||
** Description Get report descriptor of the device
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhGetDscpInfo(UINT8 dev_handle);
|
||||
|
||||
/*******************************************************************************
|
||||
** Function BTA_HhAddDev
|
||||
**
|
||||
** Description Add a virtually cabled device into HID-Host device list
|
||||
** to manage and assign a device handle for future API call,
|
||||
** host applciation call this API at start-up to initialize its
|
||||
** virtually cabled devices.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhAddDev(BD_ADDR bda, tBTA_HH_ATTR_MASK attr_mask,
|
||||
UINT8 sub_class, UINT8 app_id,
|
||||
tBTA_HH_DEV_DSCP_INFO dscp_info);
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhRemoveDev
|
||||
**
|
||||
** Description Remove a device from the HID host devices list.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhRemoveDev(UINT8 dev_handle );
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Parsing Utility Functions
|
||||
**
|
||||
*******************************************************************************/
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhParseBootRpt
|
||||
**
|
||||
** Description This utility function parse a boot mode report.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhParseBootRpt(tBTA_HH_BOOT_RPT *p_data, UINT8 *p_report,
|
||||
UINT16 report_len);
|
||||
|
||||
#if BTA_HH_LE_INCLUDED == TRUE
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_HhUpdateLeScanParam
|
||||
**
|
||||
** Description Update the scan paramteters if connected to a LE hid device as
|
||||
** report host.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void BTA_HhUpdateLeScanParam(UINT8 dev_handle, UINT16 scan_int, UINT16 scan_win);
|
||||
#endif
|
||||
/* test commands */
|
||||
extern void bta_hh_le_hid_read_rpt_clt_cfg(BD_ADDR bd_addr, UINT8 rpt_id);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BTA_HH_API_H */
|
||||
132
components/bt/bluedroid/bta/include/bta_hh_co.h
Normal file
132
components/bt/bluedroid/bta/include/bta_hh_co.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2005-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the interface file for hid host call-out functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_HH_CO_H
|
||||
#define BTA_HH_CO_H
|
||||
|
||||
#include "bta_hh_api.h"
|
||||
|
||||
typedef struct {
|
||||
UINT16 rpt_uuid;
|
||||
UINT8 rpt_id;
|
||||
tBTA_HH_RPT_TYPE rpt_type;
|
||||
UINT8 inst_id;
|
||||
UINT8 prop;
|
||||
} tBTA_HH_RPT_CACHE_ENTRY;
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_co_data
|
||||
**
|
||||
** Description This callout function is executed by HH when data is received
|
||||
** in interupt channel.
|
||||
**
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_hh_co_data(UINT8 dev_handle, UINT8 *p_rpt, UINT16 len,
|
||||
tBTA_HH_PROTO_MODE mode, UINT8 sub_class,
|
||||
UINT8 ctry_code, BD_ADDR peer_addr, UINT8 app_id);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_co_open
|
||||
**
|
||||
** Description This callout function is executed by HH when connection is
|
||||
** opened, and application may do some device specific
|
||||
** initialization.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_hh_co_open(UINT8 dev_handle, UINT8 sub_class,
|
||||
UINT16 attr_mask, UINT8 app_id);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_co_close
|
||||
**
|
||||
** Description This callout function is executed by HH when connection is
|
||||
** closed, and device specific finalizatio nmay be needed.
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_hh_co_close(UINT8 dev_handle, UINT8 app_id);
|
||||
|
||||
#if (BLE_INCLUDED == TRUE && BTA_HH_LE_INCLUDED == TRUE)
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_le_co_rpt_info
|
||||
**
|
||||
** Description This callout function is to convey the report information on
|
||||
** a HOGP device to the application. Application can save this
|
||||
** information in NV if device is bonded and load it back when
|
||||
** stack reboot.
|
||||
**
|
||||
** Parameters remote_bda - remote device address
|
||||
** p_entry - report entry pointer
|
||||
** app_id - application id
|
||||
**
|
||||
** Returns void.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_hh_le_co_rpt_info(BD_ADDR remote_bda,
|
||||
tBTA_HH_RPT_CACHE_ENTRY *p_entry,
|
||||
UINT8 app_id);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_le_co_cache_load
|
||||
**
|
||||
** Description This callout function is to request the application to load the
|
||||
** cached HOGP report if there is any. When cache reading is completed,
|
||||
** bta_hh_le_ci_cache_load() is called by the application.
|
||||
**
|
||||
** Parameters remote_bda - remote device address
|
||||
** p_num_rpt: number of cached report
|
||||
** app_id - application id
|
||||
**
|
||||
** Returns the acched report array
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern tBTA_HH_RPT_CACHE_ENTRY *bta_hh_le_co_cache_load (BD_ADDR remote_bda,
|
||||
UINT8 *p_num_rpt,
|
||||
UINT8 app_id);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_hh_le_co_reset_rpt_cache
|
||||
**
|
||||
** Description This callout function is to reset the HOGP device cache.
|
||||
**
|
||||
** Parameters remote_bda - remote device address
|
||||
**
|
||||
** Returns none
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void bta_hh_le_co_reset_rpt_cache (BD_ADDR remote_bda, UINT8 app_id);
|
||||
|
||||
#endif /* #if (BLE_INCLUDED == TRUE && BTA_HH_LE_INCLUDED == TRUE) */
|
||||
#endif /* BTA_HH_CO_H */
|
||||
142
components/bt/bluedroid/bta/include/bta_sdp_api.h
Normal file
142
components/bt/bluedroid/bta/include/bta_sdp_api.h
Normal file
@@ -0,0 +1,142 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the public interface file for the BTA SDP I/F
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_SDP_API_H
|
||||
#define BTA_SDP_API_H
|
||||
|
||||
#include "bt_sdp.h"
|
||||
#include "bt_target.h"
|
||||
#include "bt_types.h"
|
||||
#include "bta_api.h"
|
||||
#include "btm_api.h"
|
||||
|
||||
/* status values */
|
||||
#define BTA_SDP_SUCCESS 0 /* Successful operation. */
|
||||
#define BTA_SDP_FAILURE 1 /* Generic failure. */
|
||||
#define BTA_SDP_BUSY 2 /* Temporarily can not handle this request. */
|
||||
|
||||
typedef UINT8 tBTA_SDP_STATUS;
|
||||
|
||||
/* SDP I/F callback events */
|
||||
/* events received by tBTA_SDP_DM_CBACK */
|
||||
#define BTA_SDP_ENABLE_EVT 0 /* SDP service i/f enabled*/
|
||||
#define BTA_SDP_SEARCH_EVT 1 /* SDP Service started */
|
||||
#define BTA_SDP_SEARCH_COMP_EVT 2 /* SDP search complete */
|
||||
#define BTA_SDP_CREATE_RECORD_USER_EVT 3 /* SDP search complete */
|
||||
#define BTA_SDP_REMOVE_RECORD_USER_EVT 4 /* SDP search complete */
|
||||
#define BTA_SDP_MAX_EVT 5 /* max number of SDP events */
|
||||
|
||||
#define BTA_SDP_MAX_RECORDS 15
|
||||
|
||||
typedef UINT16 tBTA_SDP_EVT;
|
||||
|
||||
/* data associated with BTA_SDP_DISCOVERY_COMP_EVT */
|
||||
typedef struct {
|
||||
tBTA_SDP_STATUS status;
|
||||
BD_ADDR remote_addr;
|
||||
tBT_UUID uuid;
|
||||
int record_count;
|
||||
bluetooth_sdp_record records[BTA_SDP_MAX_RECORDS];
|
||||
} tBTA_SDP_SEARCH_COMP;
|
||||
|
||||
typedef union {
|
||||
tBTA_SDP_STATUS status; /* BTA_SDP_SEARCH_EVT */
|
||||
tBTA_SDP_SEARCH_COMP sdp_search_comp; /* BTA_SDP_SEARCH_COMP_EVT */
|
||||
} tBTA_SDP;
|
||||
|
||||
/* SDP DM Interface callback */
|
||||
typedef void (tBTA_SDP_DM_CBACK)(tBTA_SDP_EVT event, tBTA_SDP *p_data, void *user_data);
|
||||
|
||||
/* MCE configuration structure */
|
||||
typedef struct {
|
||||
UINT16 sdp_db_size; /* The size of p_sdp_db */
|
||||
tSDP_DISCOVERY_DB *p_sdp_db; /* The data buffer to keep SDP database */
|
||||
} tBTA_SDP_CFG;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_SdpEnable
|
||||
**
|
||||
** Description Enable the SDP I/F service. When the enable
|
||||
** operation is complete the callback function will be
|
||||
** called with a BTA_SDP_ENABLE_EVT. This function must
|
||||
** be called before other functions in the MCE API are
|
||||
** called.
|
||||
**
|
||||
** Returns BTA_SDP_SUCCESS if successful.
|
||||
** BTA_SDP_FAIL if internal failure.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern tBTA_SDP_STATUS BTA_SdpEnable(tBTA_SDP_DM_CBACK *p_cback);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_SdpSearch
|
||||
**
|
||||
** Description Start a search for sdp records for a specific BD_ADDR with a
|
||||
** specific profile uuid.
|
||||
** When the search operation is completed, the callback function
|
||||
** will be called with a BTA_SDP_SEARCH_EVT.
|
||||
** Returns BTA_SDP_SUCCESS if successful.
|
||||
** BTA_SDP_FAIL if internal failure.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern tBTA_SDP_STATUS BTA_SdpSearch(BD_ADDR bd_addr, tSDP_UUID *uuid);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_SdpCreateRecordByUser
|
||||
**
|
||||
** Description This function is used to request a callback to create a SDP
|
||||
** record. The registered callback will be called with event
|
||||
** BTA_SDP_CREATE_RECORD_USER_EVT.
|
||||
**
|
||||
** Returns BTA_SDP_SUCCESS, if the request is being processed.
|
||||
** BTA_SDP_FAILURE, otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern tBTA_SDP_STATUS BTA_SdpCreateRecordByUser(void *user_data);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_SdpRemoveRecordByUser
|
||||
**
|
||||
** Description This function is used to request a callback to remove a SDP
|
||||
** record. The registered callback will be called with event
|
||||
** BTA_SDP_REMOVE_RECORD_USER_EVT.
|
||||
**
|
||||
** Returns BTA_SDP_SUCCESS, if the request is being processed.
|
||||
** BTA_SDP_FAILURE, otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern tBTA_SDP_STATUS BTA_SdpRemoveRecordByUser(void *user_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BTA_SDP_API_H */
|
||||
282
components/bt/bluedroid/bta/include/bta_sys.h
Normal file
282
components/bt/bluedroid/bta/include/bta_sys.h
Normal file
@@ -0,0 +1,282 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the public interface file for the BTA system manager.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_SYS_H
|
||||
#define BTA_SYS_H
|
||||
|
||||
#include "bt_target.h"
|
||||
#include "gki.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and data types
|
||||
*****************************************************************************/
|
||||
|
||||
/* vendor specific event handler function type */
|
||||
typedef BOOLEAN (tBTA_SYS_VS_EVT_HDLR)(UINT16 evt, void *p);
|
||||
|
||||
/* event handler function type */
|
||||
typedef BOOLEAN (tBTA_SYS_EVT_HDLR)(BT_HDR *p_msg);
|
||||
|
||||
/* disable function type */
|
||||
typedef void (tBTA_SYS_DISABLE)(void);
|
||||
|
||||
|
||||
/* HW modules */
|
||||
enum {
|
||||
BTA_SYS_HW_BLUETOOTH,
|
||||
BTA_SYS_HW_RT,
|
||||
|
||||
BTA_SYS_MAX_HW_MODULES
|
||||
};
|
||||
|
||||
typedef UINT16 tBTA_SYS_HW_MODULE;
|
||||
|
||||
#ifndef BTA_DM_NUM_JV_ID
|
||||
#define BTA_DM_NUM_JV_ID 2
|
||||
#endif
|
||||
|
||||
/* SW sub-systems */
|
||||
#define BTA_ID_SYS 0 /* system manager */
|
||||
/* BLUETOOTH PART - from 0 to BTA_ID_BLUETOOTH_MAX */
|
||||
#define BTA_ID_DM 1 /* device manager */
|
||||
#define BTA_ID_DM_SEARCH 2 /* device manager search */
|
||||
#define BTA_ID_DM_SEC 3 /* device manager security */
|
||||
#define BTA_ID_DG 4 /* data gateway */
|
||||
#define BTA_ID_AG 5 /* audio gateway */
|
||||
#define BTA_ID_OPC 6 /* object push client */
|
||||
#define BTA_ID_OPS 7 /* object push server */
|
||||
#define BTA_ID_FTS 8 /* file transfer server */
|
||||
#define BTA_ID_CT 9 /* cordless telephony terminal */
|
||||
#define BTA_ID_FTC 10 /* file transfer client */
|
||||
#define BTA_ID_SS 11 /* synchronization server */
|
||||
#define BTA_ID_PR 12 /* Printer client */
|
||||
#define BTA_ID_BIC 13 /* Basic Imaging Client */
|
||||
#define BTA_ID_PAN 14 /* Personal Area Networking */
|
||||
#define BTA_ID_BIS 15 /* Basic Imaging Server */
|
||||
#define BTA_ID_ACC 16 /* Advanced Camera Client */
|
||||
#define BTA_ID_SC 17 /* SIM Card Access server */
|
||||
#define BTA_ID_AV 18 /* Advanced audio/video */
|
||||
#define BTA_ID_AVK 19 /* Audio/video sink */
|
||||
#define BTA_ID_HD 20 /* HID Device */
|
||||
#define BTA_ID_CG 21 /* Cordless Gateway */
|
||||
#define BTA_ID_BP 22 /* Basic Printing Client */
|
||||
#define BTA_ID_HH 23 /* Human Interface Device Host */
|
||||
#define BTA_ID_PBS 24 /* Phone Book Access Server */
|
||||
#define BTA_ID_PBC 25 /* Phone Book Access Client */
|
||||
#define BTA_ID_JV 26 /* Java */
|
||||
#define BTA_ID_HS 27 /* Headset */
|
||||
#define BTA_ID_MSE 28 /* Message Server Equipment */
|
||||
#define BTA_ID_MCE 29 /* Message Client Equipment */
|
||||
#define BTA_ID_HL 30 /* Health Device Profile*/
|
||||
#define BTA_ID_GATTC 31 /* GATT Client */
|
||||
#define BTA_ID_GATTS 32 /* GATT Client */
|
||||
#define BTA_ID_SDP 33 /* SDP Client */
|
||||
#define BTA_ID_BLUETOOTH_MAX 34 /* last BT profile */
|
||||
|
||||
/* GENERIC */
|
||||
#define BTA_ID_PRM 38
|
||||
#define BTA_ID_SYSTEM 39 /* platform-specific */
|
||||
#define BTA_ID_SWRAP 40 /* Insight script wrapper */
|
||||
#define BTA_ID_MIP 41 /* Multicase Individual Polling */
|
||||
#define BTA_ID_RT 42 /* Audio Routing module: This module is always on. */
|
||||
|
||||
|
||||
/* JV */
|
||||
#define BTA_ID_JV1 44 /* JV1 */
|
||||
#define BTA_ID_JV2 45 /* JV2 */
|
||||
|
||||
#define BTA_ID_MAX (44 + BTA_DM_NUM_JV_ID)
|
||||
|
||||
typedef UINT8 tBTA_SYS_ID;
|
||||
|
||||
|
||||
#define BTA_SYS_CONN_OPEN 0x00
|
||||
#define BTA_SYS_CONN_CLOSE 0x01
|
||||
#define BTA_SYS_APP_OPEN 0x02
|
||||
#define BTA_SYS_APP_CLOSE 0x03
|
||||
#define BTA_SYS_SCO_OPEN 0x04
|
||||
#define BTA_SYS_SCO_CLOSE 0x05
|
||||
#define BTA_SYS_CONN_IDLE 0x06
|
||||
#define BTA_SYS_CONN_BUSY 0x07
|
||||
|
||||
/* for link policy */
|
||||
#define BTA_SYS_PLCY_SET 0x10 /* set the link policy to the given addr */
|
||||
#define BTA_SYS_PLCY_CLR 0x11 /* clear the link policy to the given addr */
|
||||
#define BTA_SYS_PLCY_DEF_SET 0x12 /* set the default link policy */
|
||||
#define BTA_SYS_PLCY_DEF_CLR 0x13 /* clear the default link policy */
|
||||
#define BTA_SYS_ROLE_CHANGE 0x14 /* role change */
|
||||
|
||||
typedef UINT8 tBTA_SYS_CONN_STATUS;
|
||||
|
||||
/* Bitmask of sys features */
|
||||
#define BTA_SYS_FEAT_PCM2 0x0001
|
||||
#define BTA_SYS_FEAT_PCM2_MASTER 0x0002
|
||||
|
||||
/* tBTA_PREF_ROLES */
|
||||
typedef UINT8 tBTA_SYS_PREF_ROLES;
|
||||
|
||||
/* conn callback for role / low power manager*/
|
||||
typedef void (tBTA_SYS_CONN_CBACK)(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
|
||||
/* conn callback for role / low power manager*/
|
||||
typedef void (tBTA_SYS_SSR_CFG_CBACK)(UINT8 id, UINT8 app_id, UINT16 latency, UINT16 tout);
|
||||
|
||||
#if (BTA_EIR_CANNED_UUID_LIST != TRUE)
|
||||
/* eir callback for adding/removeing UUID */
|
||||
typedef void (tBTA_SYS_EIR_CBACK)(UINT16 uuid16, BOOLEAN adding);
|
||||
#endif
|
||||
|
||||
/* registration structure */
|
||||
typedef struct {
|
||||
tBTA_SYS_EVT_HDLR *evt_hdlr;
|
||||
tBTA_SYS_DISABLE *disable;
|
||||
} tBTA_SYS_REG;
|
||||
|
||||
/* data type to send events to BTA SYS HW manager */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_SYS_HW_MODULE hw_module;
|
||||
} tBTA_SYS_HW_MSG;
|
||||
|
||||
/*****************************************************************************
|
||||
** Global data
|
||||
*****************************************************************************/
|
||||
|
||||
/* trace level */
|
||||
extern UINT8 appl_trace_level;
|
||||
|
||||
/*****************************************************************************
|
||||
** Macros
|
||||
*****************************************************************************/
|
||||
|
||||
/* Calculate start of event enumeration; id is top 8 bits of event */
|
||||
#define BTA_SYS_EVT_START(id) ((id) << 8)
|
||||
|
||||
/*****************************************************************************
|
||||
** events for BTA SYS HW manager
|
||||
*****************************************************************************/
|
||||
|
||||
/* events sent to SYS HW manager - must be kept synchronized with tables in bta_sys_main.c */
|
||||
enum {
|
||||
/* device manager local device API events */
|
||||
BTA_SYS_API_ENABLE_EVT = BTA_SYS_EVT_START(BTA_ID_SYS),
|
||||
BTA_SYS_EVT_ENABLED_EVT,
|
||||
BTA_SYS_EVT_STACK_ENABLED_EVT,
|
||||
BTA_SYS_API_DISABLE_EVT,
|
||||
BTA_SYS_EVT_DISABLED_EVT,
|
||||
BTA_SYS_ERROR_EVT,
|
||||
|
||||
BTA_SYS_MAX_EVT
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* SYS HW status events - returned by SYS HW manager to other modules. */
|
||||
enum {
|
||||
BTA_SYS_HW_OFF_EVT,
|
||||
BTA_SYS_HW_ON_EVT,
|
||||
BTA_SYS_HW_STARTING_EVT,
|
||||
BTA_SYS_HW_STOPPING_EVT,
|
||||
BTA_SYS_HW_ERROR_EVT
|
||||
|
||||
};
|
||||
typedef UINT8 tBTA_SYS_HW_EVT;
|
||||
|
||||
/* HW enable callback type */
|
||||
typedef void (tBTA_SYS_HW_CBACK)(tBTA_SYS_HW_EVT status);
|
||||
|
||||
/*****************************************************************************
|
||||
** Function declarations
|
||||
*****************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern void bta_sys_init(void);
|
||||
extern void bta_sys_free(void);
|
||||
extern void bta_sys_event(BT_HDR *p_msg);
|
||||
extern void bta_sys_set_trace_level(UINT8 level);
|
||||
extern void bta_sys_register(UINT8 id, const tBTA_SYS_REG *p_reg);
|
||||
extern void bta_sys_deregister(UINT8 id);
|
||||
extern BOOLEAN bta_sys_is_register(UINT8 id);
|
||||
extern UINT16 bta_sys_get_sys_features(void);
|
||||
extern void bta_sys_sendmsg(void *p_msg);
|
||||
extern void bta_sys_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout_ms);
|
||||
extern void bta_sys_stop_timer(TIMER_LIST_ENT *p_tle);
|
||||
extern void bta_sys_disable(tBTA_SYS_HW_MODULE module);
|
||||
extern UINT32 bta_sys_get_remaining_ticks(TIMER_LIST_ENT *p_target_tle);
|
||||
|
||||
extern void bta_sys_hw_register( tBTA_SYS_HW_MODULE module, tBTA_SYS_HW_CBACK *cback);
|
||||
extern void bta_sys_hw_unregister( tBTA_SYS_HW_MODULE module );
|
||||
|
||||
|
||||
extern void bta_sys_rm_register(tBTA_SYS_CONN_CBACK *p_cback);
|
||||
extern void bta_sys_pm_register(tBTA_SYS_CONN_CBACK *p_cback);
|
||||
|
||||
extern void bta_sys_policy_register(tBTA_SYS_CONN_CBACK *p_cback);
|
||||
extern void bta_sys_sco_register(tBTA_SYS_CONN_CBACK *p_cback);
|
||||
|
||||
|
||||
extern void bta_sys_conn_open(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
extern void bta_sys_conn_close(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
extern void bta_sys_app_open(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
extern void bta_sys_app_close(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
extern void bta_sys_sco_open(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
extern void bta_sys_sco_close(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
extern void bta_sys_sco_use(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
extern void bta_sys_sco_unuse(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
extern void bta_sys_idle(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
extern void bta_sys_busy(UINT8 id, UINT8 app_id, BD_ADDR peer_addr);
|
||||
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
extern void bta_sys_ssr_cfg_register(tBTA_SYS_SSR_CFG_CBACK *p_cback);
|
||||
extern void bta_sys_chg_ssr_config (UINT8 id, UINT8 app_id, UINT16 max_latency, UINT16 min_tout);
|
||||
#endif
|
||||
|
||||
extern void bta_sys_role_chg_register(tBTA_SYS_CONN_CBACK *p_cback);
|
||||
extern void bta_sys_notify_role_chg(BD_ADDR_PTR p_bda, UINT8 new_role, UINT8 hci_status);
|
||||
extern void bta_sys_collision_register(UINT8 bta_id, tBTA_SYS_CONN_CBACK *p_cback);
|
||||
extern void bta_sys_notify_collision (BD_ADDR_PTR p_bda);
|
||||
|
||||
#if (BTA_EIR_CANNED_UUID_LIST != TRUE)
|
||||
extern void bta_sys_eir_register(tBTA_SYS_EIR_CBACK *p_cback);
|
||||
extern void bta_sys_add_uuid(UINT16 uuid16);
|
||||
extern void bta_sys_remove_uuid(UINT16 uuid16);
|
||||
#else
|
||||
#define bta_sys_eir_register(ut)
|
||||
#define bta_sys_add_uuid(ut)
|
||||
#define bta_sys_remove_uuid(ut)
|
||||
#endif
|
||||
|
||||
extern void bta_sys_set_policy (UINT8 id, UINT8 policy, BD_ADDR peer_addr);
|
||||
extern void bta_sys_clear_policy (UINT8 id, UINT8 policy, BD_ADDR peer_addr);
|
||||
extern void bta_sys_set_default_policy (UINT8 id, UINT8 policy);
|
||||
extern void bta_sys_clear_default_policy (UINT8 id, UINT8 policy);
|
||||
extern BOOLEAN bta_sys_vs_hdl(UINT16 evt, void *p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BTA_SYS_H */
|
||||
169
components/bt/bluedroid/bta/include/utl.h
Normal file
169
components/bt/bluedroid/bta/include/utl.h
Normal file
@@ -0,0 +1,169 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Basic utility functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef UTL_H
|
||||
#define UTL_H
|
||||
|
||||
#include "bt_types.h"
|
||||
// #include "bt_utils.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
/*** class of device settings ***/
|
||||
#define BTA_UTL_SET_COD_MAJOR_MINOR 0x01
|
||||
#define BTA_UTL_SET_COD_SERVICE_CLASS 0x02 /* only set the bits in the input */
|
||||
#define BTA_UTL_CLR_COD_SERVICE_CLASS 0x04
|
||||
#define BTA_UTL_SET_COD_ALL 0x08 /* take service class as the input (may clear some set bits!!) */
|
||||
#define BTA_UTL_INIT_COD 0x0a
|
||||
|
||||
/*****************************************************************************
|
||||
** Type Definitions
|
||||
*****************************************************************************/
|
||||
|
||||
/** for utl_set_device_class() **/
|
||||
typedef struct {
|
||||
UINT8 minor;
|
||||
UINT8 major;
|
||||
UINT16 service;
|
||||
} tBTA_UTL_COD;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
** External Function Declarations
|
||||
*****************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_str2int
|
||||
**
|
||||
** Description This utility function converts a character string to an
|
||||
** integer. Acceptable values in string are 0-9. If invalid
|
||||
** string or string value too large, -1 is returned.
|
||||
**
|
||||
**
|
||||
** Returns Integer value or -1 on error.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern INT16 utl_str2int(const char *p_s);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_strucmp
|
||||
**
|
||||
** Description This utility function compares two strings in uppercase.
|
||||
** String p_s must be uppercase. String p_t is converted to
|
||||
** uppercase if lowercase. If p_s ends first, the substring
|
||||
** match is counted as a match.
|
||||
**
|
||||
**
|
||||
** Returns 0 if strings match, nonzero otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern int utl_strucmp(const char *p_s, const char *p_t);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_itoa
|
||||
**
|
||||
** Description This utility function converts a UINT16 to a string. The
|
||||
** string is NULL-terminated. The length of the string is
|
||||
** returned.
|
||||
**
|
||||
**
|
||||
** Returns Length of string.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern UINT8 utl_itoa(UINT16 i, char *p_s);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_freebuf
|
||||
**
|
||||
** Description This function calls GKI_freebuf to free the buffer passed
|
||||
** in, if buffer pointer is not NULL, and also initializes
|
||||
** buffer pointer to NULL.
|
||||
**
|
||||
**
|
||||
** Returns Nothing.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void utl_freebuf(void **p);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_set_device_class
|
||||
**
|
||||
** Description This function updates the local Device Class.
|
||||
**
|
||||
** Parameters:
|
||||
** p_cod - Pointer to the device class to set to
|
||||
**
|
||||
** cmd - the fields of the device class to update.
|
||||
** BTA_UTL_SET_COD_MAJOR_MINOR, - overwrite major, minor class
|
||||
** BTA_UTL_SET_COD_SERVICE_CLASS - set the bits in the input
|
||||
** BTA_UTL_CLR_COD_SERVICE_CLASS - clear the bits in the input
|
||||
** BTA_UTL_SET_COD_ALL - overwrite major, minor, set the bits in service class
|
||||
** BTA_UTL_INIT_COD - overwrite major, minor, and service class
|
||||
**
|
||||
** Returns TRUE if successful, Otherwise FALSE
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern BOOLEAN utl_set_device_class(tBTA_UTL_COD *p_cod, UINT8 cmd);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_isintstr
|
||||
**
|
||||
** Description This utility function checks if the given string is an
|
||||
** integer string or not
|
||||
**
|
||||
**
|
||||
** Returns TRUE if successful, Otherwise FALSE
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern BOOLEAN utl_isintstr(const char *p_s);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_isdialstr
|
||||
**
|
||||
** Description This utility function checks if the given string contains
|
||||
** only dial digits or not
|
||||
**
|
||||
**
|
||||
** Returns TRUE if successful, Otherwise FALSE
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern BOOLEAN utl_isdialstr(const char *p_s);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* UTL_H */
|
||||
77
components/bt/bluedroid/bta/sdp/bta_sdp.c
Normal file
77
components/bt/bluedroid/bta/sdp/bta_sdp.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the main implementation file for the BTA MCE I/F
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "bta_api.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_sdp_api.h"
|
||||
#include "bta_sdp_int.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and types
|
||||
*****************************************************************************/
|
||||
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
tBTA_SDP_CB bta_sdp_cb;
|
||||
#endif
|
||||
|
||||
/* state machine action enumeration list */
|
||||
#define BTA_SDP_NUM_ACTIONS (BTA_SDP_MAX_INT_EVT & 0x00ff)
|
||||
|
||||
/* type for action functions */
|
||||
typedef void (*tBTA_SDP_ACTION)(tBTA_SDP_MSG *p_data);
|
||||
|
||||
/* action function list */
|
||||
const tBTA_SDP_ACTION bta_sdp_action[] = {
|
||||
bta_sdp_enable, /* BTA_SDP_API_ENABLE_EVT */
|
||||
bta_sdp_search, /* BTA_SDP_API_SEARCH_EVT */
|
||||
bta_sdp_create_record, /* BTA_SDP_API_CREATE_RECORD_USER_EVT */
|
||||
bta_sdp_remove_record, /* BTA_SDP_API_REMOVE_RECORD_USER_EVT */
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
** Function bta_sdp_sm_execute
|
||||
**
|
||||
** Description State machine event handling function for SDP search
|
||||
**
|
||||
** Returns void
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_sdp_sm_execute(BT_HDR *p_msg)
|
||||
{
|
||||
if (p_msg == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN ret = FALSE;
|
||||
UINT16 action = (p_msg->event & 0x00ff);
|
||||
|
||||
/* execute action functions */
|
||||
if (action < BTA_SDP_NUM_ACTIONS) {
|
||||
(*bta_sdp_action[action])((tBTA_SDP_MSG *)p_msg);
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
546
components/bt/bluedroid/bta/sdp/bta_sdp_act.c
Normal file
546
components/bt/bluedroid/bta/sdp/bta_sdp_act.c
Normal file
@@ -0,0 +1,546 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
* This file contains action functions for SDP search.
|
||||
******************************************************************************/
|
||||
|
||||
// #include <hardware/bluetooth.h>
|
||||
#include "bt_sdp.h"
|
||||
// #include <arpa/inet.h>
|
||||
#include "bt_defs.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "allocator.h"
|
||||
#include "bt_types.h"
|
||||
#include "gki.h"
|
||||
#include "utl.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_api.h"
|
||||
#include "bta_sdp_api.h"
|
||||
#include "bta_sdp_int.h"
|
||||
#include "btm_api.h"
|
||||
#include "btm_int.h"
|
||||
#include "sdp_api.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
|
||||
static const uint8_t UUID_OBEX_OBJECT_PUSH[] = {0x00, 0x00, 0x11, 0x05, 0x00, 0x00, 0x10, 0x00,
|
||||
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
|
||||
};
|
||||
static const uint8_t UUID_PBAP_PSE[] = {0x00, 0x00, 0x11, 0x2F, 0x00, 0x00, 0x10, 0x00,
|
||||
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
|
||||
};
|
||||
static const uint8_t UUID_MAP_MAS[] = {0x00, 0x00, 0x11, 0x32, 0x00, 0x00, 0x10, 0x00,
|
||||
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
|
||||
};
|
||||
static const uint8_t UUID_MAP_MNS[] = {0x00, 0x00, 0x11, 0x33, 0x00, 0x00, 0x10, 0x00,
|
||||
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
|
||||
};
|
||||
static const uint8_t UUID_SPP[] = {0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x10, 0x00,
|
||||
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
|
||||
};
|
||||
static const uint8_t UUID_SAP[] = {0x00, 0x00, 0x11, 0x2D, 0x00, 0x00, 0x10, 0x00,
|
||||
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
|
||||
};
|
||||
// TODO:
|
||||
// Both the fact that the UUIDs are declared in multiple places, plus the fact
|
||||
// that there is a mess of UUID comparison and shortening methods will have to
|
||||
// be fixed.
|
||||
// The btcore->uuid module should be used for all instances.
|
||||
|
||||
#define UUID_MAX_LENGTH 16
|
||||
#define IS_UUID(u1,u2) !memcmp(u1,u2,UUID_MAX_LENGTH)
|
||||
|
||||
static inline tBT_UUID shorten_sdp_uuid(const tBT_UUID *u)
|
||||
{
|
||||
static uint8_t bt_base_uuid[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
|
||||
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB
|
||||
};
|
||||
|
||||
APPL_TRACE_DEBUG("%s() - uuid len:%d\n", __func__, u->len);
|
||||
if (u->len != 16) {
|
||||
return *u;
|
||||
}
|
||||
|
||||
if (memcmp(&u->uu.uuid128[4], &bt_base_uuid[4], 12) != 0) {
|
||||
return *u;
|
||||
}
|
||||
|
||||
tBT_UUID su;
|
||||
memset(&su, 0, sizeof(su));
|
||||
if (u->uu.uuid128[0] == 0 && u->uu.uuid128[1] == 0) {
|
||||
su.len = 2;
|
||||
uint16_t u16;
|
||||
memcpy(&u16, &u->uu.uuid128[2], sizeof(u16));
|
||||
su.uu.uuid16 = ntohs(u16);
|
||||
} else {
|
||||
su.len = 4;
|
||||
uint32_t u32;
|
||||
memcpy(&u32, &u->uu.uuid128[0], sizeof(u32));
|
||||
su.uu.uuid32 = ntohl(u32);
|
||||
}
|
||||
return su;
|
||||
}
|
||||
|
||||
static void bta_create_mns_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
|
||||
{
|
||||
tSDP_DISC_ATTR *p_attr;
|
||||
tSDP_PROTOCOL_ELEM pe;
|
||||
UINT16 pversion = 0;
|
||||
record->mns.hdr.type = SDP_TYPE_MAP_MNS;
|
||||
record->mns.hdr.service_name_length = 0;
|
||||
record->mns.hdr.service_name = NULL;
|
||||
record->mns.hdr.rfcomm_channel_number = 0;
|
||||
record->mns.hdr.l2cap_psm = -1;
|
||||
record->mns.hdr.profile_version = 0;
|
||||
record->mns.supported_features = 0x0000001F; //default value if not found
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES)) != NULL) {
|
||||
record->mns.supported_features = p_attr->attr_value.v.u32;
|
||||
}
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL) {
|
||||
record->mns.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
|
||||
record->mns.hdr.service_name = (char *)p_attr->attr_value.v.array;
|
||||
}
|
||||
|
||||
if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_MAP_PROFILE, &pversion)) {
|
||||
record->mns.hdr.profile_version = pversion;
|
||||
}
|
||||
|
||||
if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
|
||||
record->mns.hdr.rfcomm_channel_number = pe.params[0];
|
||||
}
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM)) != NULL) {
|
||||
record->mns.hdr.l2cap_psm = p_attr->attr_value.v.u16;
|
||||
}
|
||||
}
|
||||
|
||||
static void bta_create_mas_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
|
||||
{
|
||||
tSDP_DISC_ATTR *p_attr;
|
||||
tSDP_PROTOCOL_ELEM pe;
|
||||
UINT16 pversion = -1;
|
||||
|
||||
record->mas.hdr.type = SDP_TYPE_MAP_MAS;
|
||||
record->mas.hdr.service_name_length = 0;
|
||||
record->mas.hdr.service_name = NULL;
|
||||
record->mas.hdr.rfcomm_channel_number = 0;
|
||||
record->mas.hdr.l2cap_psm = -1;
|
||||
record->mas.hdr.profile_version = 0;
|
||||
record->mas.mas_instance_id = 0;
|
||||
record->mas.supported_features = 0x0000001F;
|
||||
record->mas.supported_message_types = 0;
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAS_INSTANCE_ID)) != NULL) {
|
||||
record->mas.mas_instance_id = p_attr->attr_value.v.u8;
|
||||
}
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_MSG_TYPE)) != NULL) {
|
||||
record->mas.supported_message_types = p_attr->attr_value.v.u8;
|
||||
}
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_MAP_SUPPORTED_FEATURES)) != NULL) {
|
||||
record->mas.supported_features = p_attr->attr_value.v.u32;
|
||||
}
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL) {
|
||||
record->mas.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
|
||||
record->mas.hdr.service_name = (char *)p_attr->attr_value.v.array;
|
||||
}
|
||||
|
||||
if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_MAP_PROFILE, &pversion)) {
|
||||
record->mas.hdr.profile_version = pversion;
|
||||
}
|
||||
|
||||
if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
|
||||
record->mas.hdr.rfcomm_channel_number = pe.params[0];
|
||||
}
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM)) != NULL) {
|
||||
record->mas.hdr.l2cap_psm = p_attr->attr_value.v.u16;
|
||||
}
|
||||
}
|
||||
|
||||
static void bta_create_pse_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
|
||||
{
|
||||
tSDP_DISC_ATTR *p_attr;
|
||||
UINT16 pversion;
|
||||
tSDP_PROTOCOL_ELEM pe;
|
||||
|
||||
record->pse.hdr.type = SDP_TYPE_PBAP_PSE;
|
||||
record->pse.hdr.service_name_length = 0;
|
||||
record->pse.hdr.service_name = NULL;
|
||||
record->pse.hdr.rfcomm_channel_number = 0;
|
||||
record->pse.hdr.l2cap_psm = -1;
|
||||
record->pse.hdr.profile_version = 0;
|
||||
record->pse.supported_features = 0x00000003;
|
||||
record->pse.supported_repositories = 0;
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_REPOSITORIES)) != NULL) {
|
||||
record->pse.supported_repositories = p_attr->attr_value.v.u8;
|
||||
}
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PBAP_SUPPORTED_FEATURES)) != NULL) {
|
||||
record->pse.supported_features = p_attr->attr_value.v.u32;
|
||||
}
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL) {
|
||||
record->pse.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
|
||||
record->pse.hdr.service_name = (char *)p_attr->attr_value.v.array;
|
||||
}
|
||||
|
||||
if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_PHONE_ACCESS, &pversion)) {
|
||||
record->pse.hdr.profile_version = pversion;
|
||||
}
|
||||
|
||||
if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
|
||||
record->pse.hdr.rfcomm_channel_number = pe.params[0];
|
||||
}
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM)) != NULL) {
|
||||
record->pse.hdr.l2cap_psm = p_attr->attr_value.v.u16;
|
||||
}
|
||||
}
|
||||
|
||||
static void bta_create_ops_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
|
||||
{
|
||||
tSDP_DISC_ATTR *p_attr, *p_sattr;
|
||||
tSDP_PROTOCOL_ELEM pe;
|
||||
UINT16 pversion = -1;
|
||||
|
||||
record->ops.hdr.type = SDP_TYPE_OPP_SERVER;
|
||||
record->ops.hdr.service_name_length = 0;
|
||||
record->ops.hdr.service_name = NULL;
|
||||
record->ops.hdr.rfcomm_channel_number = 0;
|
||||
record->ops.hdr.l2cap_psm = -1;
|
||||
record->ops.hdr.profile_version = 0;
|
||||
record->ops.supported_formats_list_len = 0;
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL) {
|
||||
record->ops.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
|
||||
record->ops.hdr.service_name = (char *)p_attr->attr_value.v.array;
|
||||
}
|
||||
|
||||
if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_OBEX_OBJECT_PUSH, &pversion)) {
|
||||
record->ops.hdr.profile_version = pversion;
|
||||
}
|
||||
|
||||
if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
|
||||
record->ops.hdr.rfcomm_channel_number = pe.params[0];
|
||||
}
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_GOEP_L2CAP_PSM)) != NULL) {
|
||||
record->ops.hdr.l2cap_psm = p_attr->attr_value.v.u16;
|
||||
}
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SUPPORTED_FORMATS_LIST)) != NULL) {
|
||||
/* Safety check - each entry should itself be a sequence */
|
||||
if (SDP_DISC_ATTR_TYPE(p_attr->attr_len_type) != DATA_ELE_SEQ_DESC_TYPE) {
|
||||
record->ops.supported_formats_list_len = 0;
|
||||
APPL_TRACE_ERROR("%s() - supported_formats_list - wrong attribute length/type:"
|
||||
" 0x%02x - expected 0x06", __func__, p_attr->attr_len_type);
|
||||
} else {
|
||||
int count = 0;
|
||||
/* 1 byte for type/length 1 byte for value */
|
||||
record->ops.supported_formats_list_len = SDP_DISC_ATTR_LEN(p_attr->attr_len_type) / 2;
|
||||
|
||||
/* Extract each value into */
|
||||
for (p_sattr = p_attr->attr_value.v.p_sub_attr;
|
||||
p_sattr != NULL; p_sattr = p_sattr->p_next_attr) {
|
||||
if ((SDP_DISC_ATTR_TYPE(p_sattr->attr_len_type) == UINT_DESC_TYPE)
|
||||
&& (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) == 1)) {
|
||||
if (count == sizeof(record->ops.supported_formats_list)) {
|
||||
APPL_TRACE_ERROR("%s() - supported_formats_list - count overflow - "
|
||||
"too many sub attributes!!\n", __func__);
|
||||
/* If you hit this, new formats have been added,
|
||||
* update SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH */
|
||||
break;
|
||||
}
|
||||
record->ops.supported_formats_list[count] = p_sattr->attr_value.v.u8;
|
||||
count++;
|
||||
} else {
|
||||
APPL_TRACE_ERROR("%s() - supported_formats_list - wrong sub attribute "
|
||||
"length/type: 0x%02x - expected 0x80", __func__,
|
||||
p_sattr->attr_len_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (record->ops.supported_formats_list_len != count) {
|
||||
APPL_TRACE_WARNING("%s() - supported_formats_list - Length of attribute different "
|
||||
"from the actual number of sub-attributes in the sequence "
|
||||
"att-length: %d - number of elements: %d\n", __func__,
|
||||
record->ops.supported_formats_list_len , count);
|
||||
|
||||
}
|
||||
record->ops.supported_formats_list_len = count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void bta_create_sap_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
|
||||
{
|
||||
tSDP_DISCOVERY_DB *db = p_bta_sdp_cfg->p_sdp_db;
|
||||
tSDP_DISC_ATTR *p_attr;
|
||||
tSDP_PROTOCOL_ELEM pe;
|
||||
UINT16 pversion = -1;
|
||||
|
||||
record->sap.hdr.type = SDP_TYPE_MAP_MAS;
|
||||
record->sap.hdr.service_name_length = 0;
|
||||
record->sap.hdr.service_name = NULL;
|
||||
record->sap.hdr.rfcomm_channel_number = 0;
|
||||
record->sap.hdr.l2cap_psm = -1;
|
||||
record->sap.hdr.profile_version = 0;
|
||||
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL) {
|
||||
record->sap.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
|
||||
record->sap.hdr.service_name = (char *)p_attr->attr_value.v.array;
|
||||
}
|
||||
|
||||
if (SDP_FindProfileVersionInRec(p_rec, UUID_SERVCLASS_SAP, &pversion)) {
|
||||
record->sap.hdr.profile_version = pversion;
|
||||
}
|
||||
|
||||
if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
|
||||
record->sap.hdr.rfcomm_channel_number = pe.params[0];
|
||||
}
|
||||
}
|
||||
|
||||
static void bta_create_raw_sdp_record(bluetooth_sdp_record *record, tSDP_DISC_REC *p_rec)
|
||||
{
|
||||
tSDP_DISC_ATTR *p_attr;
|
||||
tSDP_PROTOCOL_ELEM pe;
|
||||
|
||||
record->hdr.type = SDP_TYPE_RAW;
|
||||
record->hdr.service_name_length = 0;
|
||||
record->hdr.service_name = NULL;
|
||||
record->hdr.rfcomm_channel_number = -1;
|
||||
record->hdr.l2cap_psm = -1;
|
||||
record->hdr.profile_version = -1;
|
||||
|
||||
/* Try to extract a service name */
|
||||
if ((p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME)) != NULL) {
|
||||
record->pse.hdr.service_name_length = SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
|
||||
record->pse.hdr.service_name = (char *)p_attr->attr_value.v.array;
|
||||
}
|
||||
|
||||
/* Try to extract an RFCOMM channel */
|
||||
if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_RFCOMM, &pe)) {
|
||||
record->pse.hdr.rfcomm_channel_number = pe.params[0];
|
||||
}
|
||||
record->hdr.user1_ptr_len = p_bta_sdp_cfg->p_sdp_db->raw_size;
|
||||
record->hdr.user1_ptr = p_bta_sdp_cfg->p_sdp_db->raw_data;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sdp_search_cback
|
||||
**
|
||||
** Description Callback from btm after search is completed
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void bta_sdp_search_cback(UINT16 result, void *user_data)
|
||||
{
|
||||
tSDP_DISC_REC *p_rec = NULL;
|
||||
tBTA_SDP_SEARCH_COMP evt_data = {0}; // We need to zero-initialize
|
||||
tBTA_SDP_STATUS status = BTA_SDP_FAILURE;
|
||||
int count = 0;
|
||||
tBT_UUID su;
|
||||
APPL_TRACE_DEBUG("%s() - res: 0x%x\n", __func__, result);
|
||||
|
||||
bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_NONE;
|
||||
|
||||
if (bta_sdp_cb.p_dm_cback == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
bdcpy(evt_data.remote_addr, bta_sdp_cb.remote_addr);
|
||||
tBT_UUID *uuid = (tBT_UUID *)user_data;
|
||||
memcpy(&evt_data.uuid, uuid, sizeof(tBT_UUID));
|
||||
su = shorten_sdp_uuid(uuid);
|
||||
|
||||
if (result == SDP_SUCCESS || result == SDP_DB_FULL) {
|
||||
do {
|
||||
p_rec = SDP_FindServiceUUIDInDb(p_bta_sdp_cfg->p_sdp_db, &su, p_rec);
|
||||
/* generate the matching record data pointer */
|
||||
if (p_rec != NULL) {
|
||||
status = BTA_SDP_SUCCESS;
|
||||
if (IS_UUID(UUID_MAP_MAS, uuid->uu.uuid128)) {
|
||||
APPL_TRACE_DEBUG("%s() - found MAP (MAS) uuid\n", __func__);
|
||||
bta_create_mas_sdp_record(&evt_data.records[count], p_rec);
|
||||
} else if (IS_UUID(UUID_MAP_MNS, uuid->uu.uuid128)) {
|
||||
APPL_TRACE_DEBUG("%s() - found MAP (MNS) uuid\n", __func__);
|
||||
bta_create_mns_sdp_record(&evt_data.records[count], p_rec);
|
||||
} else if (IS_UUID(UUID_PBAP_PSE, uuid->uu.uuid128)) {
|
||||
APPL_TRACE_DEBUG("%s() - found PBAP (PSE) uuid\n", __func__);
|
||||
bta_create_pse_sdp_record(&evt_data.records[count], p_rec);
|
||||
} else if (IS_UUID(UUID_OBEX_OBJECT_PUSH, uuid->uu.uuid128)) {
|
||||
APPL_TRACE_DEBUG("%s() - found Object Push Server (OPS) uuid\n", __func__);
|
||||
bta_create_ops_sdp_record(&evt_data.records[count], p_rec);
|
||||
} else if (IS_UUID(UUID_SAP, uuid->uu.uuid128)) {
|
||||
APPL_TRACE_DEBUG("%s() - found SAP uuid\n", __func__);
|
||||
bta_create_sap_sdp_record(&evt_data.records[count], p_rec);
|
||||
} else {
|
||||
|
||||
/* we do not have specific structure for this */
|
||||
APPL_TRACE_DEBUG("%s() - profile not identified. using raw data\n", __func__);
|
||||
bta_create_raw_sdp_record(&evt_data.records[count], p_rec);
|
||||
p_rec = NULL; // Terminate loop
|
||||
/* For raw, we only extract the first entry, and then return the entire
|
||||
raw data chunk.
|
||||
TODO: Find a way to split the raw data into record chunks, and iterate
|
||||
to extract generic data for each chunk - e.g. rfcomm channel and
|
||||
service name. */
|
||||
}
|
||||
count++;
|
||||
} else {
|
||||
APPL_TRACE_DEBUG("%s() - UUID not found\n", __func__);
|
||||
}
|
||||
} while (p_rec != NULL && count < BTA_SDP_MAX_RECORDS);
|
||||
|
||||
evt_data.record_count = count;
|
||||
}
|
||||
evt_data.status = status;
|
||||
|
||||
bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, (tBTA_SDP *) &evt_data, (void *)&uuid->uu.uuid128);
|
||||
osi_free(user_data); // We no longer need the user data to track the search
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sdp_enable
|
||||
**
|
||||
** Description Initializes the SDP I/F
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sdp_enable(tBTA_SDP_MSG *p_data)
|
||||
{
|
||||
APPL_TRACE_DEBUG("%s in, sdp_active:%d\n", __func__, bta_sdp_cb.sdp_active);
|
||||
tBTA_SDP_STATUS status = BTA_SDP_SUCCESS;
|
||||
bta_sdp_cb.p_dm_cback = p_data->enable.p_cback;
|
||||
bta_sdp_cb.p_dm_cback(BTA_SDP_ENABLE_EVT, (tBTA_SDP *)&status, NULL);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sdp_search
|
||||
**
|
||||
** Description Discovers all sdp records for an uuid on remote device
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sdp_search(tBTA_SDP_MSG *p_data)
|
||||
{
|
||||
int x = 0;
|
||||
// TODO: Leaks!!! but needed as user-data pointer
|
||||
tBT_UUID *bta_sdp_search_uuid = osi_malloc(sizeof(tBT_UUID));
|
||||
if (p_data == NULL) {
|
||||
APPL_TRACE_DEBUG("SDP control block handle is null\n");
|
||||
return;
|
||||
}
|
||||
tBTA_SDP_STATUS status = BTA_SDP_FAILURE;
|
||||
|
||||
APPL_TRACE_DEBUG("%s in, sdp_active:%d\n", __func__, bta_sdp_cb.sdp_active);
|
||||
|
||||
if (bta_sdp_cb.sdp_active != BTA_SDP_ACTIVE_NONE) {
|
||||
/* SDP is still in progress */
|
||||
status = BTA_SDP_BUSY;
|
||||
if (bta_sdp_cb.p_dm_cback) {
|
||||
tBTA_SDP_SEARCH_COMP result = {0};
|
||||
result.uuid = p_data->get_search.uuid;
|
||||
bdcpy(result.remote_addr, p_data->get_search.bd_addr);
|
||||
result.status = status;
|
||||
bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, (tBTA_SDP *)&result, NULL);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_YES;
|
||||
bdcpy(bta_sdp_cb.remote_addr, p_data->get_search.bd_addr);
|
||||
/* set the uuid used in the search */
|
||||
memcpy(bta_sdp_search_uuid, &(p_data->get_search.uuid), sizeof(tBT_UUID));
|
||||
|
||||
/* initialize the search for the uuid */
|
||||
APPL_TRACE_DEBUG("%s init discovery with UUID(len: %d):\n",
|
||||
__func__, bta_sdp_search_uuid->len);
|
||||
for (x = 0; x < bta_sdp_search_uuid->len; x++) {
|
||||
APPL_TRACE_DEBUG("%X", bta_sdp_search_uuid->uu.uuid128[x]);
|
||||
}
|
||||
SDP_InitDiscoveryDb (p_bta_sdp_cfg->p_sdp_db, p_bta_sdp_cfg->sdp_db_size, 1,
|
||||
bta_sdp_search_uuid, 0, NULL);
|
||||
|
||||
if (!SDP_ServiceSearchAttributeRequest2(p_data->get_search.bd_addr, p_bta_sdp_cfg->p_sdp_db,
|
||||
bta_sdp_search_cback, (void *)bta_sdp_search_uuid)) {
|
||||
bta_sdp_cb.sdp_active = BTA_SDP_ACTIVE_NONE;
|
||||
|
||||
/* failed to start SDP. report the failure right away */
|
||||
if (bta_sdp_cb.p_dm_cback) {
|
||||
tBTA_SDP_SEARCH_COMP result = {0};
|
||||
result.uuid = p_data->get_search.uuid;
|
||||
bdcpy(result.remote_addr, p_data->get_search.bd_addr);
|
||||
result.status = status;
|
||||
bta_sdp_cb.p_dm_cback(BTA_SDP_SEARCH_COMP_EVT, (tBTA_SDP *)&result, NULL);
|
||||
}
|
||||
}
|
||||
/*
|
||||
else report the result when the cback is called
|
||||
*/
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sdp_record
|
||||
**
|
||||
** Description Discovers all sdp records for an uuid on remote device
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sdp_create_record(tBTA_SDP_MSG *p_data)
|
||||
{
|
||||
APPL_TRACE_DEBUG("%s() event: %d\n", __func__, p_data->record.hdr.event);
|
||||
if (bta_sdp_cb.p_dm_cback) {
|
||||
bta_sdp_cb.p_dm_cback(BTA_SDP_CREATE_RECORD_USER_EVT, NULL, p_data->record.user_data);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sdp_create_record
|
||||
**
|
||||
** Description Discovers all sdp records for an uuid on remote device
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sdp_remove_record(tBTA_SDP_MSG *p_data)
|
||||
{
|
||||
APPL_TRACE_DEBUG("%s() event: %d\n", __func__, p_data->record.hdr.event);
|
||||
if (bta_sdp_cb.p_dm_cback) {
|
||||
bta_sdp_cb.p_dm_cback(BTA_SDP_REMOVE_RECORD_USER_EVT, NULL, p_data->record.user_data);
|
||||
}
|
||||
}
|
||||
167
components/bt/bluedroid/bta/sdp/bta_sdp_api.c
Normal file
167
components/bt/bluedroid/bta/sdp/bta_sdp_api.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the implementation of the API for SDP search subsystem
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "bta_api.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_sdp_api.h"
|
||||
#include "bta_sdp_int.h"
|
||||
#include "gki.h"
|
||||
#include <string.h>
|
||||
// #include "port_api.h"
|
||||
#include "sdp_api.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
|
||||
static const tBTA_SYS_REG bta_sdp_reg = {
|
||||
bta_sdp_sm_execute,
|
||||
NULL
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_SdpEnable
|
||||
**
|
||||
** Description Enable the SDP search I/F service. When the enable
|
||||
** operation is complete the callback function will be
|
||||
** called with a BTA_SDP_ENABLE_EVT. This function must
|
||||
** be called before other functions in the SDP search API are
|
||||
** called.
|
||||
**
|
||||
** Returns BTA_SDP_SUCCESS if successful.
|
||||
** BTA_SDP_FAIL if internal failure.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_SDP_STATUS BTA_SdpEnable(tBTA_SDP_DM_CBACK *p_cback)
|
||||
{
|
||||
tBTA_SDP_STATUS status = BTA_SDP_FAILURE;
|
||||
tBTA_SDP_API_ENABLE *p_buf;
|
||||
|
||||
APPL_TRACE_API("%s\n", __FUNCTION__);
|
||||
if (p_cback && FALSE == bta_sys_is_register(BTA_ID_SDP)) {
|
||||
memset(&bta_sdp_cb, 0, sizeof(tBTA_SDP_CB));
|
||||
|
||||
/* register with BTA system manager */
|
||||
bta_sys_register(BTA_ID_SDP, &bta_sdp_reg);
|
||||
|
||||
if (p_cback &&
|
||||
(p_buf = (tBTA_SDP_API_ENABLE *) GKI_getbuf(sizeof(tBTA_SDP_API_ENABLE))) != NULL) {
|
||||
p_buf->hdr.event = BTA_SDP_API_ENABLE_EVT;
|
||||
p_buf->p_cback = p_cback;
|
||||
bta_sys_sendmsg(p_buf);
|
||||
status = BTA_SDP_SUCCESS;
|
||||
}
|
||||
}
|
||||
return (status);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_SdpSearch
|
||||
**
|
||||
** Description This function performs service discovery for a specific service
|
||||
** on given peer device. When the operation is completed
|
||||
** the tBTA_SDP_DM_CBACK callback function will be called with
|
||||
** a BTA_SDP_SEARCH_COMPLETE_EVT.
|
||||
**
|
||||
** Returns BTA_SDP_SUCCESS, if the request is being processed.
|
||||
** BTA_SDP_FAILURE, otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_SDP_STATUS BTA_SdpSearch(BD_ADDR bd_addr, tSDP_UUID *uuid)
|
||||
{
|
||||
tBTA_SDP_STATUS ret = BTA_SDP_FAILURE;
|
||||
tBTA_SDP_API_SEARCH *p_msg;
|
||||
|
||||
APPL_TRACE_API("%s\n", __FUNCTION__);
|
||||
if ((p_msg = (tBTA_SDP_API_SEARCH *)GKI_getbuf(sizeof(tBTA_SDP_API_SEARCH))) != NULL) {
|
||||
p_msg->hdr.event = BTA_SDP_API_SEARCH_EVT;
|
||||
bdcpy(p_msg->bd_addr, bd_addr);
|
||||
//p_msg->uuid = uuid;
|
||||
memcpy(&(p_msg->uuid), uuid, sizeof(tSDP_UUID));
|
||||
bta_sys_sendmsg(p_msg);
|
||||
ret = BTA_SDP_SUCCESS;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_SdpCreateRecordByUser
|
||||
**
|
||||
** Description This function is used to request a callback to create a SDP
|
||||
** record. The registered callback will be called with event
|
||||
** BTA_SDP_CREATE_RECORD_USER_EVT.
|
||||
**
|
||||
** Returns BTA_SDP_SUCCESS, if the request is being processed.
|
||||
** BTA_SDP_FAILURE, otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_SDP_STATUS BTA_SdpCreateRecordByUser(void *user_data)
|
||||
{
|
||||
tBTA_SDP_STATUS ret = BTA_SDP_FAILURE;
|
||||
tBTA_SDP_API_RECORD_USER *p_msg;
|
||||
|
||||
APPL_TRACE_API("%s\n", __FUNCTION__);
|
||||
if ((p_msg = (tBTA_SDP_API_RECORD_USER *)GKI_getbuf(sizeof(tBTA_SDP_API_RECORD_USER))) != NULL) {
|
||||
p_msg->hdr.event = BTA_SDP_API_CREATE_RECORD_USER_EVT;
|
||||
p_msg->user_data = user_data;
|
||||
bta_sys_sendmsg(p_msg);
|
||||
ret = BTA_SDP_SUCCESS;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_SdpRemoveRecordByUser
|
||||
**
|
||||
** Description This function is used to request a callback to remove a SDP
|
||||
** record. The registered callback will be called with event
|
||||
** BTA_SDP_REMOVE_RECORD_USER_EVT.
|
||||
**
|
||||
** Returns BTA_SDP_SUCCESS, if the request is being processed.
|
||||
** BTA_SDP_FAILURE, otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_SDP_STATUS BTA_SdpRemoveRecordByUser(void *user_data)
|
||||
{
|
||||
tBTA_SDP_STATUS ret = BTA_SDP_FAILURE;
|
||||
tBTA_SDP_API_RECORD_USER *p_msg;
|
||||
|
||||
APPL_TRACE_API("%s\n", __FUNCTION__);
|
||||
if ((p_msg = (tBTA_SDP_API_RECORD_USER *)GKI_getbuf(sizeof(tBTA_SDP_API_RECORD_USER))) != NULL) {
|
||||
p_msg->hdr.event = BTA_SDP_API_REMOVE_RECORD_USER_EVT;
|
||||
p_msg->user_data = user_data;
|
||||
bta_sys_sendmsg(p_msg);
|
||||
ret = BTA_SDP_SUCCESS;
|
||||
}
|
||||
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
39
components/bt/bluedroid/bta/sdp/bta_sdp_cfg.c
Normal file
39
components/bt/bluedroid/bta/sdp/bta_sdp_cfg.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
* This file contains compile-time configurable constants for SDP Search
|
||||
******************************************************************************/
|
||||
|
||||
#include "gki.h"
|
||||
#include "bta_api.h"
|
||||
#include "bta_sdp_api.h"
|
||||
|
||||
#ifndef BTA_SDP_DB_SIZE
|
||||
#define BTA_SDP_DB_SIZE 4500
|
||||
#endif
|
||||
|
||||
static UINT8 __attribute__ ((aligned(4))) bta_sdp_db_data[BTA_SDP_DB_SIZE];
|
||||
|
||||
/* SDP configuration structure */
|
||||
const tBTA_SDP_CFG bta_sdp_cfg = {
|
||||
BTA_SDP_DB_SIZE,
|
||||
(tSDP_DISCOVERY_DB *)bta_sdp_db_data /* The data buffer to keep SDP database */
|
||||
};
|
||||
|
||||
tBTA_SDP_CFG *p_bta_sdp_cfg = (tBTA_SDP_CFG *) &bta_sdp_cfg;
|
||||
108
components/bt/bluedroid/bta/sdp/bta_sdp_int.h
Normal file
108
components/bt/bluedroid/bta/sdp/bta_sdp_int.h
Normal file
@@ -0,0 +1,108 @@
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the private interface file for the BTA SDP I/F
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_SDP_INT_H
|
||||
#define BTA_SDP_INT_H
|
||||
|
||||
#include "bta_sys.h"
|
||||
#include "bta_api.h"
|
||||
#include "bta_sdp_api.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
|
||||
enum {
|
||||
/* these events are handled by the state machine */
|
||||
BTA_SDP_API_ENABLE_EVT = BTA_SYS_EVT_START(BTA_ID_SDP),
|
||||
BTA_SDP_API_SEARCH_EVT,
|
||||
BTA_SDP_API_CREATE_RECORD_USER_EVT,
|
||||
BTA_SDP_API_REMOVE_RECORD_USER_EVT,
|
||||
BTA_SDP_MAX_INT_EVT
|
||||
};
|
||||
|
||||
enum {
|
||||
BTA_SDP_ACTIVE_NONE = 0,
|
||||
BTA_SDP_ACTIVE_YES /* waiting for SDP result */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* data type for BTA_SDP_API_ENABLE_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
tBTA_SDP_DM_CBACK *p_cback;
|
||||
} tBTA_SDP_API_ENABLE;
|
||||
|
||||
/* data type for BTA_SDP_API_SEARCH_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR bd_addr;
|
||||
tSDP_UUID uuid;
|
||||
} tBTA_SDP_API_SEARCH;
|
||||
|
||||
/* data type for BTA_SDP_API_SEARCH_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
void *user_data;
|
||||
} tBTA_SDP_API_RECORD_USER;
|
||||
|
||||
/* union of all data types */
|
||||
typedef union {
|
||||
/* GKI event buffer header */
|
||||
BT_HDR hdr;
|
||||
tBTA_SDP_API_ENABLE enable;
|
||||
tBTA_SDP_API_SEARCH get_search;
|
||||
tBTA_SDP_API_RECORD_USER record;
|
||||
} tBTA_SDP_MSG;
|
||||
|
||||
/* SDP control block */
|
||||
typedef struct {
|
||||
UINT8 sdp_active; /* see BTA_SDP_SDP_ACT_* */
|
||||
BD_ADDR remote_addr;
|
||||
tBTA_SDP_DM_CBACK *p_dm_cback;
|
||||
} tBTA_SDP_CB;
|
||||
|
||||
|
||||
/* SDP control block */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
extern tBTA_SDP_CB bta_sdp_cb;
|
||||
#else
|
||||
extern tBTA_SDP_CB *bta_sdp_cb_ptr;
|
||||
#define bta_sdp_cb (*bta_sdp_cb_ptr)
|
||||
#endif
|
||||
|
||||
/* config struct */
|
||||
extern tBTA_SDP_CFG *p_bta_sdp_cfg;
|
||||
|
||||
extern BOOLEAN bta_sdp_sm_execute(BT_HDR *p_msg);
|
||||
|
||||
extern void bta_sdp_enable (tBTA_SDP_MSG *p_data);
|
||||
extern void bta_sdp_search (tBTA_SDP_MSG *p_data);
|
||||
extern void bta_sdp_create_record(tBTA_SDP_MSG *p_data);
|
||||
extern void bta_sdp_remove_record(tBTA_SDP_MSG *p_data);
|
||||
|
||||
#endif /* BTA_SDP_INT_H */
|
||||
571
components/bt/bluedroid/bta/sys/bta_sys_conn.c
Normal file
571
components/bt/bluedroid/bta/sys/bta_sys_conn.c
Normal file
@@ -0,0 +1,571 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Routes connection status callbacks from various sub systems to DM
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "bta_api.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_sys_int.h"
|
||||
#include "gki.h"
|
||||
#include "utl.h"
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_rm_register
|
||||
**
|
||||
** Description Called by BTA DM to register role management callbacks
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_rm_register(tBTA_SYS_CONN_CBACK *p_cback)
|
||||
{
|
||||
bta_sys_cb.prm_cb = p_cback;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_policy_register
|
||||
**
|
||||
** Description Called by BTA DM to register link policy change callbacks
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_policy_register(tBTA_SYS_CONN_CBACK *p_cback)
|
||||
{
|
||||
bta_sys_cb.p_policy_cb = p_cback;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_role_chg_register
|
||||
**
|
||||
** Description Called by BTA AV to register role change callbacks
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_role_chg_register(tBTA_SYS_CONN_CBACK *p_cback)
|
||||
{
|
||||
bta_sys_cb.p_role_cb = p_cback;
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_ssr_cfg_register
|
||||
**
|
||||
** Description Called by BTA DM to register SSR configuration callback
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
void bta_sys_ssr_cfg_register(tBTA_SYS_SSR_CFG_CBACK *p_cback)
|
||||
{
|
||||
bta_sys_cb.p_ssr_cb = p_cback;
|
||||
}
|
||||
#endif
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_role_chg_register
|
||||
**
|
||||
** Description Called by BTA AV to register role change callbacks
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_notify_role_chg(BD_ADDR_PTR p_bda, UINT8 new_role, UINT8 hci_status)
|
||||
{
|
||||
if (bta_sys_cb.p_role_cb) {
|
||||
bta_sys_cb.p_role_cb(BTA_SYS_ROLE_CHANGE, new_role, hci_status, p_bda);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_collision_register
|
||||
**
|
||||
** Description Called by any BTA module to register for collision event.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_collision_register(UINT8 bta_id, tBTA_SYS_CONN_CBACK *p_cback)
|
||||
{
|
||||
UINT8 index;
|
||||
|
||||
for (index = 0; index < MAX_COLLISION_REG; index++) {
|
||||
if ((bta_sys_cb.colli_reg.id[index] == bta_id) ||
|
||||
(bta_sys_cb.colli_reg.id[index] == 0)) {
|
||||
bta_sys_cb.colli_reg.id[index] = bta_id;
|
||||
bta_sys_cb.colli_reg.p_coll_cback[index] = p_cback;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_notify_collision
|
||||
**
|
||||
** Description Called by BTA DM to notify collision event.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_notify_collision (BD_ADDR_PTR p_bda)
|
||||
{
|
||||
UINT8 index;
|
||||
|
||||
for (index = 0; index < MAX_COLLISION_REG; index++) {
|
||||
if ((bta_sys_cb.colli_reg.id[index] != 0) &&
|
||||
(bta_sys_cb.colli_reg.p_coll_cback[index] != NULL)) {
|
||||
bta_sys_cb.colli_reg.p_coll_cback[index] (0, BTA_ID_SYS, 0, p_bda);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_sco_register
|
||||
**
|
||||
** Description Called by BTA AV to register sco connection change callbacks
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_sco_register(tBTA_SYS_CONN_CBACK *p_cback)
|
||||
{
|
||||
bta_sys_cb.p_sco_cb = p_cback;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_pm_register
|
||||
**
|
||||
** Description Called by BTA DM to register power management callbacks
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_pm_register(tBTA_SYS_CONN_CBACK *p_cback)
|
||||
{
|
||||
bta_sys_cb.ppm_cb = p_cback;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_conn_open
|
||||
**
|
||||
** Description Called by BTA subsystems when a connection is made to
|
||||
** the service
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_conn_open(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
if (bta_sys_cb.prm_cb) {
|
||||
|
||||
bta_sys_cb.prm_cb(BTA_SYS_CONN_OPEN, id, app_id, peer_addr);
|
||||
|
||||
}
|
||||
|
||||
if (bta_sys_cb.ppm_cb) {
|
||||
|
||||
bta_sys_cb.ppm_cb(BTA_SYS_CONN_OPEN, id, app_id, peer_addr);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_conn_close
|
||||
**
|
||||
** Description Called by BTA subsystems when a connection to the service
|
||||
** is closed
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_conn_close(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
if (bta_sys_cb.prm_cb) {
|
||||
|
||||
bta_sys_cb.prm_cb(BTA_SYS_CONN_CLOSE, id, app_id, peer_addr);
|
||||
|
||||
}
|
||||
|
||||
if (bta_sys_cb.ppm_cb) {
|
||||
|
||||
bta_sys_cb.ppm_cb(BTA_SYS_CONN_CLOSE, id, app_id, peer_addr);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_app_open
|
||||
**
|
||||
** Description Called by BTA subsystems when application initiates connection
|
||||
** to a peer device
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_app_open(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
if (bta_sys_cb.ppm_cb) {
|
||||
bta_sys_cb.ppm_cb(BTA_SYS_APP_OPEN, id, app_id, peer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_app_close
|
||||
**
|
||||
** Description Called by BTA subsystems when application initiates close
|
||||
** of connection to peer device
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_app_close(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
if (bta_sys_cb.ppm_cb) {
|
||||
bta_sys_cb.ppm_cb(BTA_SYS_APP_CLOSE, id, app_id, peer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_sco_open
|
||||
**
|
||||
** Description Called by BTA subsystems when sco connection for that service
|
||||
** is open
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_sco_open(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
/* AG triggers p_sco_cb by bta_sys_sco_use. */
|
||||
if ((id != BTA_ID_AG) && (bta_sys_cb.p_sco_cb)) {
|
||||
/* without querying BTM_GetNumScoLinks() */
|
||||
bta_sys_cb.p_sco_cb(BTA_SYS_SCO_OPEN, 1, app_id, peer_addr);
|
||||
}
|
||||
|
||||
if (bta_sys_cb.ppm_cb) {
|
||||
bta_sys_cb.ppm_cb(BTA_SYS_SCO_OPEN, id, app_id, peer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_sco_close
|
||||
**
|
||||
** Description Called by BTA subsystems when sco connection for that service
|
||||
** is closed
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_sco_close(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
UINT8 num_sco_links;
|
||||
|
||||
if ((id != BTA_ID_AG) && (bta_sys_cb.p_sco_cb)) {
|
||||
num_sco_links = BTM_GetNumScoLinks();
|
||||
bta_sys_cb.p_sco_cb(BTA_SYS_SCO_CLOSE, num_sco_links, app_id, peer_addr);
|
||||
}
|
||||
|
||||
if (bta_sys_cb.ppm_cb) {
|
||||
bta_sys_cb.ppm_cb(BTA_SYS_SCO_CLOSE, id, app_id, peer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_sco_use
|
||||
**
|
||||
** Description Called by BTA subsystems when that service needs to use sco.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_sco_use(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
UNUSED(id);
|
||||
|
||||
/* AV streaming need to be suspended before SCO is connected. */
|
||||
if (bta_sys_cb.p_sco_cb) {
|
||||
/* without querying BTM_GetNumScoLinks() */
|
||||
bta_sys_cb.p_sco_cb(BTA_SYS_SCO_OPEN, 1, app_id, peer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_sco_unuse
|
||||
**
|
||||
** Description Called by BTA subsystems when sco connection for that service
|
||||
** is no longer needed.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_sco_unuse(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
UINT8 num_sco_links;
|
||||
UNUSED(id);
|
||||
|
||||
if ((bta_sys_cb.p_sco_cb)) {
|
||||
num_sco_links = BTM_GetNumScoLinks();
|
||||
bta_sys_cb.p_sco_cb(BTA_SYS_SCO_CLOSE, num_sco_links, app_id, peer_addr);
|
||||
}
|
||||
}
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_chg_ssr_config
|
||||
**
|
||||
** Description Called by BTA subsystems to indicate that the given app SSR setting
|
||||
** need to be changed.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
void bta_sys_chg_ssr_config (UINT8 id, UINT8 app_id, UINT16 max_latency, UINT16 min_tout)
|
||||
{
|
||||
if (bta_sys_cb.p_ssr_cb) {
|
||||
bta_sys_cb.p_ssr_cb(id, app_id, max_latency, min_tout);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_set_policy
|
||||
**
|
||||
** Description Called by BTA subsystems to indicate that the given link
|
||||
** policy to peer device should be set
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_set_policy (UINT8 id, UINT8 policy, BD_ADDR peer_addr)
|
||||
{
|
||||
if (bta_sys_cb.p_policy_cb) {
|
||||
bta_sys_cb.p_policy_cb(BTA_SYS_PLCY_SET, id, policy, peer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_clear_policy
|
||||
**
|
||||
** Description Called by BTA subsystems to indicate that the given link
|
||||
** policy to peer device should be clear
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_clear_policy (UINT8 id, UINT8 policy, BD_ADDR peer_addr)
|
||||
{
|
||||
if (bta_sys_cb.p_policy_cb) {
|
||||
bta_sys_cb.p_policy_cb(BTA_SYS_PLCY_CLR, id, policy, peer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_set_default_policy
|
||||
**
|
||||
** Description Called by BTA subsystems to indicate that the given default
|
||||
** link policy should be set
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_set_default_policy (UINT8 id, UINT8 policy)
|
||||
{
|
||||
if (bta_sys_cb.p_policy_cb) {
|
||||
bta_sys_cb.p_policy_cb(BTA_SYS_PLCY_DEF_SET, id, policy, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_clear_default_policy
|
||||
**
|
||||
** Description Called by BTA subsystems to indicate that the given default
|
||||
** link policy should be clear
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_clear_default_policy (UINT8 id, UINT8 policy)
|
||||
{
|
||||
if (bta_sys_cb.p_policy_cb) {
|
||||
bta_sys_cb.p_policy_cb(BTA_SYS_PLCY_DEF_CLR, id, policy, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_idle
|
||||
**
|
||||
** Description Called by BTA subsystems to indicate that the connection to
|
||||
** peer device is idle
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_idle(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
|
||||
if (bta_sys_cb.prm_cb) {
|
||||
|
||||
bta_sys_cb.prm_cb(BTA_SYS_CONN_IDLE, id, app_id, peer_addr);
|
||||
|
||||
}
|
||||
|
||||
if (bta_sys_cb.ppm_cb) {
|
||||
|
||||
bta_sys_cb.ppm_cb(BTA_SYS_CONN_IDLE, id, app_id, peer_addr);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_busy
|
||||
**
|
||||
** Description Called by BTA subsystems to indicate that the connection to
|
||||
** peer device is busy
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_busy(UINT8 id, UINT8 app_id, BD_ADDR peer_addr)
|
||||
{
|
||||
if (bta_sys_cb.prm_cb) {
|
||||
|
||||
bta_sys_cb.prm_cb(BTA_SYS_CONN_BUSY, id, app_id, peer_addr);
|
||||
|
||||
}
|
||||
|
||||
if (bta_sys_cb.ppm_cb) {
|
||||
|
||||
bta_sys_cb.ppm_cb(BTA_SYS_CONN_BUSY, id, app_id, peer_addr);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#if (BTA_EIR_CANNED_UUID_LIST != TRUE)
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_eir_register
|
||||
**
|
||||
** Description Called by BTA DM to register EIR utility function that can be
|
||||
** used by the other BTA modules to add/remove UUID.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_eir_register(tBTA_SYS_EIR_CBACK *p_cback)
|
||||
{
|
||||
bta_sys_cb.eir_cb = p_cback;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_add_uuid
|
||||
**
|
||||
** Description Called by BTA subsystems to indicate to DM that new service
|
||||
** class UUID is added.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_add_uuid(UINT16 uuid16)
|
||||
{
|
||||
if (bta_sys_cb.eir_cb) {
|
||||
bta_sys_cb.eir_cb(uuid16, TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_remove_uuid
|
||||
**
|
||||
** Description Called by BTA subsystems to indicate to DM that the service
|
||||
** class UUID is removed.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_remove_uuid(UINT16 uuid16)
|
||||
{
|
||||
if (bta_sys_cb.eir_cb) {
|
||||
bta_sys_cb.eir_cb(uuid16, FALSE);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_vs_hdl
|
||||
**
|
||||
** Description Called by BTA subsystems to execute a VS event handler function
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_sys_vs_hdl(UINT16 evt, void *p)
|
||||
{
|
||||
if (bta_sys_cb.p_vs_evt_hdlr) {
|
||||
return (*bta_sys_cb.p_vs_evt_hdlr)(evt, p);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
727
components/bt/bluedroid/bta/sys/bta_sys_main.c
Normal file
727
components/bt/bluedroid/bta/sys/bta_sys_main.c
Normal file
@@ -0,0 +1,727 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the main implementation file for the BTA system manager.
|
||||
*
|
||||
******************************************************************************/
|
||||
#define LOG_TAG "bt_bta_sys_main"
|
||||
|
||||
// #include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "alarm.h"
|
||||
#include "thread.h"
|
||||
#include "btm_api.h"
|
||||
#include "bta_api.h"
|
||||
#include "bta_sys.h"
|
||||
#include "bta_sys_int.h"
|
||||
|
||||
#include "fixed_queue.h"
|
||||
#include "gki.h"
|
||||
#include "hash_map.h"
|
||||
#include "osi.h"
|
||||
#include "hash_functions.h"
|
||||
// #include "osi/include/log.h"
|
||||
// #include "osi/include/thread.h"
|
||||
#if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
|
||||
#include "bta_ar_api.h"
|
||||
#endif
|
||||
#include "utl.h"
|
||||
|
||||
|
||||
/* system manager control block definition */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
tBTA_SYS_CB bta_sys_cb;
|
||||
#endif
|
||||
|
||||
fixed_queue_t *btu_bta_alarm_queue;
|
||||
static hash_map_t *bta_alarm_hash_map;
|
||||
static const size_t BTA_ALARM_HASH_MAP_SIZE = 17;
|
||||
static pthread_mutex_t bta_alarm_lock;
|
||||
// extern thread_t *bt_workqueue_thread;
|
||||
|
||||
/* trace level */
|
||||
/* TODO Bluedroid - Hard-coded trace levels - Needs to be configurable */
|
||||
UINT8 appl_trace_level = BT_TRACE_LEVEL_WARNING; //APPL_INITIAL_TRACE_LEVEL;
|
||||
UINT8 btif_trace_level = BT_TRACE_LEVEL_WARNING;
|
||||
|
||||
// Communication queue between btu_task and bta.
|
||||
extern fixed_queue_t *btu_bta_msg_queue;
|
||||
void btu_bta_alarm_ready(fixed_queue_t *queue);
|
||||
|
||||
static const tBTA_SYS_REG bta_sys_hw_reg = {
|
||||
bta_sys_sm_execute,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/* type for action functions */
|
||||
typedef void (*tBTA_SYS_ACTION)(tBTA_SYS_HW_MSG *p_data);
|
||||
|
||||
/* action function list */
|
||||
const tBTA_SYS_ACTION bta_sys_action[] = {
|
||||
/* device manager local device API events - cf bta_sys.h for events */
|
||||
bta_sys_hw_api_enable, /* 0 BTA_SYS_HW_API_ENABLE_EVT */
|
||||
bta_sys_hw_evt_enabled, /* 1 BTA_SYS_HW_EVT_ENABLED_EVT */
|
||||
bta_sys_hw_evt_stack_enabled, /* 2 BTA_SYS_HW_EVT_STACK_ENABLED_EVT */
|
||||
bta_sys_hw_api_disable, /* 3 BTA_SYS_HW_API_DISABLE_EVT */
|
||||
bta_sys_hw_evt_disabled, /* 4 BTA_SYS_HW_EVT_DISABLED_EVT */
|
||||
bta_sys_hw_error /* 5 BTA_SYS_HW_ERROR_EVT */
|
||||
};
|
||||
|
||||
/* state machine action enumeration list */
|
||||
enum {
|
||||
/* device manager local device API events */
|
||||
BTA_SYS_HW_API_ENABLE,
|
||||
BTA_SYS_HW_EVT_ENABLED,
|
||||
BTA_SYS_HW_EVT_STACK_ENABLED,
|
||||
BTA_SYS_HW_API_DISABLE,
|
||||
BTA_SYS_HW_EVT_DISABLED,
|
||||
BTA_SYS_HW_ERROR
|
||||
};
|
||||
|
||||
#define BTA_SYS_NUM_ACTIONS (BTA_SYS_MAX_EVT & 0x00ff)
|
||||
#define BTA_SYS_IGNORE BTA_SYS_NUM_ACTIONS
|
||||
|
||||
/* state table information */
|
||||
#define BTA_SYS_ACTIONS 2 /* number of actions */
|
||||
#define BTA_SYS_NEXT_STATE 2 /* position of next state */
|
||||
#define BTA_SYS_NUM_COLS 3 /* number of columns in state tables */
|
||||
|
||||
|
||||
/* state table for OFF state */
|
||||
const UINT8 bta_sys_hw_off[][BTA_SYS_NUM_COLS] = {
|
||||
/* Event Action 1 Action 2 Next State */
|
||||
/* API_ENABLE */ {BTA_SYS_HW_API_ENABLE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING},
|
||||
/* EVT_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING},
|
||||
/* STACK_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
|
||||
/* API_DISABLE */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_IGNORE, BTA_SYS_HW_OFF},
|
||||
/* EVT_DISABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_OFF},
|
||||
/* EVT_ERROR */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_OFF}
|
||||
};
|
||||
|
||||
const UINT8 bta_sys_hw_starting[][BTA_SYS_NUM_COLS] = {
|
||||
/* Event Action 1 Action 2 Next State */
|
||||
/* API_ENABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING}, /* wait for completion event */
|
||||
/* EVT_ENABLED */ {BTA_SYS_HW_EVT_ENABLED, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING},
|
||||
/* STACK_ENABLED */ {BTA_SYS_HW_EVT_STACK_ENABLED, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
|
||||
/* API_DISABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING}, /* successive disable/enable: change state wait for completion to disable */
|
||||
/* EVT_DISABLED */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_HW_API_ENABLE, BTA_SYS_HW_STARTING}, /* successive enable/disable: notify, then restart HW */
|
||||
/* EVT_ERROR */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON}
|
||||
};
|
||||
|
||||
const UINT8 bta_sys_hw_on[][BTA_SYS_NUM_COLS] = {
|
||||
/* Event Action 1 Action 2 Next State */
|
||||
/* API_ENABLE */ {BTA_SYS_HW_API_ENABLE, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
|
||||
/* EVT_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
|
||||
/* STACK_ENABLED */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
|
||||
/* API_DISABLE */ {BTA_SYS_HW_API_DISABLE, BTA_SYS_IGNORE, BTA_SYS_HW_ON}, /* don't change the state here, as some other modules might be active */
|
||||
/* EVT_DISABLED */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON},
|
||||
/* EVT_ERROR */ {BTA_SYS_HW_ERROR, BTA_SYS_IGNORE, BTA_SYS_HW_ON}
|
||||
};
|
||||
|
||||
const UINT8 bta_sys_hw_stopping[][BTA_SYS_NUM_COLS] = {
|
||||
/* Event Action 1 Action 2 Next State */
|
||||
/* API_ENABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STARTING}, /* change state, and wait for completion event to enable */
|
||||
/* EVT_ENABLED */ {BTA_SYS_HW_EVT_ENABLED, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING}, /* successive enable/disable: finish the enable before disabling */
|
||||
/* STACK_ENABLED */ {BTA_SYS_HW_EVT_STACK_ENABLED, BTA_SYS_HW_API_DISABLE, BTA_SYS_HW_STOPPING}, /* successive enable/disable: notify, then stop */
|
||||
/* API_DISABLE */ {BTA_SYS_IGNORE, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING}, /* wait for completion event */
|
||||
/* EVT_DISABLED */ {BTA_SYS_HW_EVT_DISABLED, BTA_SYS_IGNORE, BTA_SYS_HW_OFF},
|
||||
/* EVT_ERROR */ {BTA_SYS_HW_API_DISABLE, BTA_SYS_IGNORE, BTA_SYS_HW_STOPPING}
|
||||
};
|
||||
|
||||
typedef const UINT8 (*tBTA_SYS_ST_TBL)[BTA_SYS_NUM_COLS];
|
||||
|
||||
/* state table */
|
||||
const tBTA_SYS_ST_TBL bta_sys_st_tbl[] = {
|
||||
bta_sys_hw_off,
|
||||
bta_sys_hw_starting,
|
||||
bta_sys_hw_on,
|
||||
bta_sys_hw_stopping
|
||||
};
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_init
|
||||
**
|
||||
** Description BTA initialization; called from task initialization.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_init(void)
|
||||
{
|
||||
memset(&bta_sys_cb, 0, sizeof(tBTA_SYS_CB));
|
||||
|
||||
pthread_mutex_init(&bta_alarm_lock, NULL);
|
||||
|
||||
bta_alarm_hash_map = hash_map_new(BTA_ALARM_HASH_MAP_SIZE,
|
||||
hash_function_pointer, NULL, (data_free_fn)osi_alarm_free, NULL);
|
||||
btu_bta_alarm_queue = fixed_queue_new(SIZE_MAX);
|
||||
|
||||
fixed_queue_register_dequeue(btu_bta_alarm_queue,
|
||||
btu_bta_alarm_ready);
|
||||
|
||||
appl_trace_level = APPL_INITIAL_TRACE_LEVEL;
|
||||
|
||||
/* register BTA SYS message handler */
|
||||
bta_sys_register( BTA_ID_SYS, &bta_sys_hw_reg);
|
||||
|
||||
/* register for BTM notifications */
|
||||
BTM_RegisterForDeviceStatusNotif ((tBTM_DEV_STATUS_CB *)&bta_sys_hw_btm_cback );
|
||||
|
||||
#if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
|
||||
bta_ar_init();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void bta_sys_free(void)
|
||||
{
|
||||
fixed_queue_free(btu_bta_alarm_queue, NULL);
|
||||
hash_map_free(bta_alarm_hash_map);
|
||||
pthread_mutex_destroy(&bta_alarm_lock);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_sm_execute
|
||||
**
|
||||
** Description State machine event handling function for DM
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_sys_sm_execute(BT_HDR *p_msg)
|
||||
{
|
||||
BOOLEAN freebuf = TRUE;
|
||||
tBTA_SYS_ST_TBL state_table;
|
||||
UINT8 action;
|
||||
int i;
|
||||
|
||||
APPL_TRACE_EVENT("bta_sys_sm_execute state:%d, event:0x%x\n", bta_sys_cb.state, p_msg->event);
|
||||
|
||||
/* look up the state table for the current state */
|
||||
state_table = bta_sys_st_tbl[bta_sys_cb.state];
|
||||
/* update state */
|
||||
bta_sys_cb.state = state_table[p_msg->event & 0x00ff][BTA_SYS_NEXT_STATE];
|
||||
|
||||
/* execute action functions */
|
||||
for (i = 0; i < BTA_SYS_ACTIONS; i++) {
|
||||
if ((action = state_table[p_msg->event & 0x00ff][i]) != BTA_SYS_IGNORE) {
|
||||
(*bta_sys_action[action])( (tBTA_SYS_HW_MSG *) p_msg);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return freebuf;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void bta_sys_hw_register( tBTA_SYS_HW_MODULE module, tBTA_SYS_HW_CBACK *cback)
|
||||
{
|
||||
bta_sys_cb.sys_hw_cback[module] = cback;
|
||||
}
|
||||
|
||||
|
||||
void bta_sys_hw_unregister( tBTA_SYS_HW_MODULE module )
|
||||
{
|
||||
bta_sys_cb.sys_hw_cback[module] = NULL;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_hw_btm_cback
|
||||
**
|
||||
** Description This function is registered by BTA SYS to BTM in order to get status notifications
|
||||
**
|
||||
**
|
||||
** Returns
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_hw_btm_cback( tBTM_DEV_STATUS status )
|
||||
{
|
||||
|
||||
tBTA_SYS_HW_MSG *sys_event;
|
||||
|
||||
APPL_TRACE_DEBUG(" bta_sys_hw_btm_cback was called with parameter: %i" , status );
|
||||
|
||||
/* send a message to BTA SYS */
|
||||
if ((sys_event = (tBTA_SYS_HW_MSG *) GKI_getbuf(sizeof(tBTA_SYS_HW_MSG))) != NULL) {
|
||||
if (status == BTM_DEV_STATUS_UP) {
|
||||
sys_event->hdr.event = BTA_SYS_EVT_STACK_ENABLED_EVT;
|
||||
} else if (status == BTM_DEV_STATUS_DOWN) {
|
||||
sys_event->hdr.event = BTA_SYS_ERROR_EVT;
|
||||
} else {
|
||||
/* BTM_DEV_STATUS_CMD_TOUT is ignored for now. */
|
||||
GKI_freebuf (sys_event);
|
||||
sys_event = NULL;
|
||||
}
|
||||
|
||||
if (sys_event) {
|
||||
bta_sys_sendmsg(sys_event);
|
||||
}
|
||||
} else {
|
||||
APPL_TRACE_DEBUG("ERROR bta_sys_hw_btm_cback couldn't send msg" );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_hw_error
|
||||
**
|
||||
** Description In case the HW device stops answering... Try to turn it off, then re-enable all
|
||||
** previously active SW modules.
|
||||
**
|
||||
** Returns success or failure
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_hw_error(tBTA_SYS_HW_MSG *p_sys_hw_msg)
|
||||
{
|
||||
UINT8 module_index;
|
||||
UNUSED(p_sys_hw_msg);
|
||||
|
||||
APPL_TRACE_DEBUG("%s\n", __FUNCTION__);
|
||||
|
||||
for (module_index = 0; module_index < BTA_SYS_MAX_HW_MODULES; module_index++) {
|
||||
if ( bta_sys_cb.sys_hw_module_active & ((UINT32)1 << module_index )) {
|
||||
switch ( module_index) {
|
||||
case BTA_SYS_HW_BLUETOOTH:
|
||||
/* Send BTA_SYS_HW_ERROR_EVT to DM */
|
||||
if (bta_sys_cb.sys_hw_cback[module_index] != NULL) {
|
||||
bta_sys_cb.sys_hw_cback[module_index] (BTA_SYS_HW_ERROR_EVT);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
/* not yet supported */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_hw_enable
|
||||
**
|
||||
** Description this function is called after API enable and HW has been turned on
|
||||
**
|
||||
**
|
||||
** Returns success or failure
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
||||
void bta_sys_hw_api_enable( tBTA_SYS_HW_MSG *p_sys_hw_msg )
|
||||
{
|
||||
if ((!bta_sys_cb.sys_hw_module_active) && (bta_sys_cb.state != BTA_SYS_HW_ON)) {
|
||||
/* register which HW module was turned on */
|
||||
bta_sys_cb.sys_hw_module_active |= ((UINT32)1 << p_sys_hw_msg->hw_module );
|
||||
|
||||
tBTA_SYS_HW_MSG *p_msg;
|
||||
if ((p_msg = (tBTA_SYS_HW_MSG *) GKI_getbuf(sizeof(tBTA_SYS_HW_MSG))) != NULL) {
|
||||
p_msg->hdr.event = BTA_SYS_EVT_ENABLED_EVT;
|
||||
p_msg->hw_module = p_sys_hw_msg->hw_module;
|
||||
|
||||
bta_sys_sendmsg(p_msg);
|
||||
}
|
||||
} else {
|
||||
/* register which HW module was turned on */
|
||||
bta_sys_cb.sys_hw_module_active |= ((UINT32)1 << p_sys_hw_msg->hw_module );
|
||||
|
||||
/* HW already in use, so directly notify the caller */
|
||||
if (bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ] != NULL ) {
|
||||
bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ]( BTA_SYS_HW_ON_EVT );
|
||||
}
|
||||
}
|
||||
|
||||
APPL_TRACE_EVENT ("bta_sys_hw_api_enable for %d, active modules 0x%04X\n",
|
||||
p_sys_hw_msg->hw_module, bta_sys_cb.sys_hw_module_active);
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_hw_disable
|
||||
**
|
||||
** Description if no other module is using the HW, this function will call ( if defined ) a user-macro to turn off the HW
|
||||
**
|
||||
**
|
||||
** Returns success or failure
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_hw_api_disable(tBTA_SYS_HW_MSG *p_sys_hw_msg)
|
||||
{
|
||||
APPL_TRACE_DEBUG("bta_sys_hw_api_disable for %d, active modules: 0x%04X\n",
|
||||
p_sys_hw_msg->hw_module, bta_sys_cb.sys_hw_module_active );
|
||||
|
||||
/* make sure the related SW blocks were stopped */
|
||||
bta_sys_disable( p_sys_hw_msg->hw_module );
|
||||
|
||||
|
||||
/* register which module we turn off */
|
||||
bta_sys_cb.sys_hw_module_active &= ~((UINT32)1 << p_sys_hw_msg->hw_module );
|
||||
|
||||
|
||||
/* if there are still some SW modules using the HW, just provide an answer to the calling */
|
||||
if ( bta_sys_cb.sys_hw_module_active != 0 ) {
|
||||
/* if there are still some SW modules using the HW, directly notify the caller */
|
||||
if ( bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ] != NULL ) {
|
||||
bta_sys_cb.sys_hw_cback[p_sys_hw_msg->hw_module ]( BTA_SYS_HW_OFF_EVT );
|
||||
}
|
||||
} else {
|
||||
/* manually update the state of our system */
|
||||
bta_sys_cb.state = BTA_SYS_HW_STOPPING;
|
||||
|
||||
tBTA_SYS_HW_MSG *p_msg;
|
||||
if ((p_msg = (tBTA_SYS_HW_MSG *) GKI_getbuf(sizeof(tBTA_SYS_HW_MSG))) != NULL) {
|
||||
p_msg->hdr.event = BTA_SYS_EVT_DISABLED_EVT;
|
||||
p_msg->hw_module = p_sys_hw_msg->hw_module;
|
||||
|
||||
bta_sys_sendmsg(p_msg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_hw_event_enabled
|
||||
**
|
||||
** Description
|
||||
**
|
||||
**
|
||||
** Returns success or failure
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_hw_evt_enabled(tBTA_SYS_HW_MSG *p_sys_hw_msg)
|
||||
{
|
||||
APPL_TRACE_EVENT("bta_sys_hw_evt_enabled for %i\n", p_sys_hw_msg->hw_module);
|
||||
BTM_DeviceReset( NULL );
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_hw_event_disabled
|
||||
**
|
||||
** Description
|
||||
**
|
||||
**
|
||||
** Returns success or failure
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_hw_evt_disabled(tBTA_SYS_HW_MSG *p_sys_hw_msg)
|
||||
{
|
||||
UINT8 hw_module_index;
|
||||
|
||||
APPL_TRACE_DEBUG("bta_sys_hw_evt_disabled - module 0x%X\n", p_sys_hw_msg->hw_module);
|
||||
|
||||
for (hw_module_index = 0; hw_module_index < BTA_SYS_MAX_HW_MODULES; hw_module_index++) {
|
||||
if (bta_sys_cb.sys_hw_cback[hw_module_index] != NULL) {
|
||||
bta_sys_cb.sys_hw_cback[hw_module_index] (BTA_SYS_HW_OFF_EVT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_hw_event_stack_enabled
|
||||
**
|
||||
** Description we receive this event once the SW side is ready ( stack, FW download,... ),
|
||||
** i.e. we can really start using the device. So notify the app.
|
||||
**
|
||||
** Returns success or failure
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_hw_evt_stack_enabled(tBTA_SYS_HW_MSG *p_sys_hw_msg)
|
||||
{
|
||||
UINT8 hw_module_index;
|
||||
UNUSED(p_sys_hw_msg);
|
||||
|
||||
APPL_TRACE_DEBUG(" bta_sys_hw_evt_stack_enabled!notify the callers\n");
|
||||
|
||||
for (hw_module_index = 0; hw_module_index < BTA_SYS_MAX_HW_MODULES; hw_module_index++ ) {
|
||||
if (bta_sys_cb.sys_hw_cback[hw_module_index] != NULL) {
|
||||
bta_sys_cb.sys_hw_cback[hw_module_index] (BTA_SYS_HW_ON_EVT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_event
|
||||
**
|
||||
** Description BTA event handler; called from task event handler.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_event(BT_HDR *p_msg)
|
||||
{
|
||||
UINT8 id;
|
||||
BOOLEAN freebuf = TRUE;
|
||||
|
||||
APPL_TRACE_EVENT("BTA got event 0x%x\n", p_msg->event);
|
||||
|
||||
/* get subsystem id from event */
|
||||
id = (UINT8) (p_msg->event >> 8);
|
||||
|
||||
/* verify id and call subsystem event handler */
|
||||
if ((id < BTA_ID_MAX) && (bta_sys_cb.reg[id] != NULL)) {
|
||||
freebuf = (*bta_sys_cb.reg[id]->evt_hdlr)(p_msg);
|
||||
} else {
|
||||
APPL_TRACE_WARNING("BTA got unregistered event id %d\n", id);
|
||||
}
|
||||
|
||||
if (freebuf) {
|
||||
GKI_freebuf(p_msg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_register
|
||||
**
|
||||
** Description Called by other BTA subsystems to register their event
|
||||
** handler.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_register(UINT8 id, const tBTA_SYS_REG *p_reg)
|
||||
{
|
||||
bta_sys_cb.reg[id] = (tBTA_SYS_REG *) p_reg;
|
||||
bta_sys_cb.is_reg[id] = TRUE;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_deregister
|
||||
**
|
||||
** Description Called by other BTA subsystems to de-register
|
||||
** handler.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_deregister(UINT8 id)
|
||||
{
|
||||
bta_sys_cb.is_reg[id] = FALSE;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_is_register
|
||||
**
|
||||
** Description Called by other BTA subsystems to get registeration
|
||||
** status.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN bta_sys_is_register(UINT8 id)
|
||||
{
|
||||
return bta_sys_cb.is_reg[id];
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_sendmsg
|
||||
**
|
||||
** Description Send a GKI message to BTA. This function is designed to
|
||||
** optimize sending of messages to BTA. It is called by BTA
|
||||
** API functions and call-in functions.
|
||||
**
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_sendmsg(void *p_msg)
|
||||
{
|
||||
// There is a race condition that occurs if the stack is shut down while
|
||||
// there is a procedure in progress that can schedule a task via this
|
||||
// message queue. This causes |btu_bta_msg_queue| to get cleaned up before
|
||||
// it gets used here; hence we check for NULL before using it.
|
||||
if (btu_bta_msg_queue) {
|
||||
fixed_queue_enqueue(btu_bta_msg_queue, p_msg);
|
||||
//ke_event_set(KE_EVENT_BTU_TASK_THREAD);
|
||||
btu_task_post(SIG_BTU_WORK);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_start_timer
|
||||
**
|
||||
** Description Start a protocol timer for the specified amount
|
||||
** of time in milliseconds.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_alarm_cb(void *data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
TIMER_LIST_ENT *p_tle = (TIMER_LIST_ENT *)data;
|
||||
|
||||
fixed_queue_enqueue(btu_bta_alarm_queue, p_tle);
|
||||
}
|
||||
|
||||
void bta_sys_start_timer(TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout_ms)
|
||||
{
|
||||
assert(p_tle != NULL);
|
||||
|
||||
// Get the alarm for this p_tle.
|
||||
pthread_mutex_lock(&bta_alarm_lock);
|
||||
if (!hash_map_has_key(bta_alarm_hash_map, p_tle)) {
|
||||
hash_map_set(bta_alarm_hash_map, p_tle, osi_alarm_new("bta_sys", bta_alarm_cb, p_tle, 0));
|
||||
}
|
||||
pthread_mutex_unlock(&bta_alarm_lock);
|
||||
|
||||
osi_alarm_t *alarm = hash_map_get(bta_alarm_hash_map, p_tle);
|
||||
if (alarm == NULL) {
|
||||
LOG_ERROR("%s unable to create alarm.", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
p_tle->event = type;
|
||||
p_tle->ticks = timeout_ms;
|
||||
//osi_alarm_set(alarm, (period_ms_t)timeout_ms, bta_alarm_cb, p_tle);
|
||||
osi_alarm_set(alarm, (period_ms_t)timeout_ms);
|
||||
}
|
||||
|
||||
bool hash_iter_ro_cb(hash_map_entry_t *hash_map_entry, void *context)
|
||||
{
|
||||
osi_alarm_t *alarm = (osi_alarm_t *)hash_map_entry->data;
|
||||
period_ms_t *p_remaining_ms = (period_ms_t *)context;
|
||||
*p_remaining_ms += osi_alarm_get_remaining_ms(alarm);
|
||||
return true;
|
||||
}
|
||||
|
||||
UINT32 bta_sys_get_remaining_ticks(TIMER_LIST_ENT *p_target_tle)
|
||||
{
|
||||
period_ms_t remaining_ms = 0;
|
||||
pthread_mutex_lock(&bta_alarm_lock);
|
||||
// Get the alarm for this p_tle
|
||||
hash_map_foreach(bta_alarm_hash_map, hash_iter_ro_cb, &remaining_ms);
|
||||
pthread_mutex_unlock(&bta_alarm_lock);
|
||||
return remaining_ms;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_stop_timer
|
||||
**
|
||||
** Description Stop a BTA timer.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_stop_timer(TIMER_LIST_ENT *p_tle)
|
||||
{
|
||||
assert(p_tle != NULL);
|
||||
|
||||
osi_alarm_t *alarm = hash_map_get(bta_alarm_hash_map, p_tle);
|
||||
if (alarm == NULL) {
|
||||
LOG_DEBUG("%s expected alarm was not in bta alarm hash map.", __func__);
|
||||
return;
|
||||
}
|
||||
osi_alarm_cancel(alarm);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_disable
|
||||
**
|
||||
** Description For each registered subsystem execute its disable function.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_disable(tBTA_SYS_HW_MODULE module)
|
||||
{
|
||||
int bta_id = 0;
|
||||
int bta_id_max = 0;
|
||||
|
||||
APPL_TRACE_DEBUG("bta_sys_disable: module %i", module);
|
||||
|
||||
switch ( module ) {
|
||||
case BTA_SYS_HW_BLUETOOTH:
|
||||
bta_id = BTA_ID_DM;
|
||||
bta_id_max = BTA_ID_BLUETOOTH_MAX;
|
||||
break;
|
||||
default:
|
||||
APPL_TRACE_WARNING("bta_sys_disable: unkown module");
|
||||
return;
|
||||
}
|
||||
|
||||
for ( ; bta_id <= bta_id_max; bta_id++) {
|
||||
if (bta_sys_cb.reg[bta_id] != NULL) {
|
||||
if (bta_sys_cb.is_reg[bta_id] == TRUE && bta_sys_cb.reg[bta_id]->disable != NULL) {
|
||||
(*bta_sys_cb.reg[bta_id]->disable)();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_set_trace_level
|
||||
**
|
||||
** Description Set trace level for BTA
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_sys_set_trace_level(UINT8 level)
|
||||
{
|
||||
appl_trace_level = level;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_sys_get_sys_features
|
||||
**
|
||||
** Description Returns sys_features to other BTA modules.
|
||||
**
|
||||
** Returns sys_features
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT16 bta_sys_get_sys_features (void)
|
||||
{
|
||||
return bta_sys_cb.sys_features;
|
||||
}
|
||||
101
components/bt/bluedroid/bta/sys/include/bta_sys_int.h
Normal file
101
components/bt/bluedroid/bta/sys/include/bta_sys_int.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2003-2012 Broadcom Corporation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at:
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This is the private interface file for the BTA system manager.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BTA_SYS_INT_H
|
||||
#define BTA_SYS_INT_H
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and data types
|
||||
*****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
** state table
|
||||
*****************************************************************************/
|
||||
|
||||
/* SYS HW state */
|
||||
enum {
|
||||
BTA_SYS_HW_OFF,
|
||||
BTA_SYS_HW_STARTING,
|
||||
BTA_SYS_HW_ON,
|
||||
BTA_SYS_HW_STOPPING
|
||||
};
|
||||
typedef UINT8 tBTA_SYS_HW_STATE;
|
||||
|
||||
/* Collision callback */
|
||||
#define MAX_COLLISION_REG 5
|
||||
|
||||
typedef struct {
|
||||
UINT8 id[MAX_COLLISION_REG];
|
||||
tBTA_SYS_CONN_CBACK *p_coll_cback[MAX_COLLISION_REG];
|
||||
} tBTA_SYS_COLLISION;
|
||||
|
||||
/* system manager control block */
|
||||
typedef struct {
|
||||
tBTA_SYS_REG *reg[BTA_ID_MAX]; /* registration structures */
|
||||
BOOLEAN is_reg[BTA_ID_MAX]; /* registration structures */
|
||||
tBTA_SYS_HW_STATE state;
|
||||
tBTA_SYS_HW_CBACK *sys_hw_cback[BTA_SYS_MAX_HW_MODULES]; /* enable callback for each HW modules */
|
||||
UINT32 sys_hw_module_active; /* bitmask of all active modules */
|
||||
UINT16 sys_features; /* Bitmask of sys features */
|
||||
|
||||
tBTA_SYS_CONN_CBACK *prm_cb; /* role management callback registered by DM */
|
||||
tBTA_SYS_CONN_CBACK *ppm_cb; /* low power management callback registered by DM */
|
||||
tBTA_SYS_CONN_CBACK *p_policy_cb; /* link policy change callback registered by DM */
|
||||
tBTA_SYS_CONN_CBACK *p_sco_cb; /* SCO connection change callback registered by AV */
|
||||
tBTA_SYS_CONN_CBACK *p_role_cb; /* role change callback registered by AV */
|
||||
tBTA_SYS_COLLISION colli_reg; /* collision handling module */
|
||||
#if (BTA_EIR_CANNED_UUID_LIST != TRUE)
|
||||
tBTA_SYS_EIR_CBACK *eir_cb; /* add/remove UUID into EIR */
|
||||
#endif
|
||||
#if (BTM_SSR_INCLUDED == TRUE)
|
||||
tBTA_SYS_SSR_CFG_CBACK *p_ssr_cb;
|
||||
#endif
|
||||
/* VS event handler */
|
||||
tBTA_SYS_VS_EVT_HDLR *p_vs_evt_hdlr;
|
||||
|
||||
} tBTA_SYS_CB;
|
||||
|
||||
/*****************************************************************************
|
||||
** Global variables
|
||||
*****************************************************************************/
|
||||
|
||||
/* system manager control block */
|
||||
#if BTA_DYNAMIC_MEMORY == FALSE
|
||||
extern tBTA_SYS_CB bta_sys_cb;
|
||||
#else
|
||||
extern tBTA_SYS_CB *bta_sys_cb_ptr;
|
||||
#define bta_sys_cb (*bta_sys_cb_ptr)
|
||||
#endif
|
||||
|
||||
/* functions used for BTA SYS HW state machine */
|
||||
void bta_sys_hw_btm_cback( tBTM_DEV_STATUS status );
|
||||
void bta_sys_hw_error(tBTA_SYS_HW_MSG *p_sys_hw_msg);
|
||||
void bta_sys_hw_api_enable( tBTA_SYS_HW_MSG *p_sys_hw_msg );
|
||||
void bta_sys_hw_api_disable(tBTA_SYS_HW_MSG *p_sys_hw_msg);
|
||||
void bta_sys_hw_evt_enabled(tBTA_SYS_HW_MSG *p_sys_hw_msg);
|
||||
void bta_sys_hw_evt_disabled(tBTA_SYS_HW_MSG *p_sys_hw_msg);
|
||||
void bta_sys_hw_evt_stack_enabled(tBTA_SYS_HW_MSG *p_sys_hw_msg);
|
||||
|
||||
BOOLEAN bta_sys_sm_execute(BT_HDR *p_msg);
|
||||
|
||||
#endif /* BTA_SYS_INT_H */
|
||||
290
components/bt/bluedroid/bta/sys/utl.c
Normal file
290
components/bt/bluedroid/bta/sys/utl.c
Normal file
@@ -0,0 +1,290 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* 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 utility functions.
|
||||
*
|
||||
******************************************************************************/
|
||||
#include <stddef.h>
|
||||
#include "utl.h"
|
||||
#include "gki.h"
|
||||
#include "btm_api.h"
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_str2int
|
||||
**
|
||||
** Description This utility function converts a character string to an
|
||||
** integer. Acceptable values in string are 0-9. If invalid
|
||||
** string or string value too large, -1 is returned. Leading
|
||||
** spaces are skipped.
|
||||
**
|
||||
**
|
||||
** Returns Integer value or -1 on error.
|
||||
**
|
||||
*******************************************************************************/
|
||||
INT16 utl_str2int(const char *p_s)
|
||||
{
|
||||
INT32 val = 0;
|
||||
|
||||
for (; *p_s == ' ' && *p_s != 0; p_s++);
|
||||
|
||||
if (*p_s == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if ((*p_s < '0') || (*p_s > '9')) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
val += (INT32) (*p_s++ - '0');
|
||||
|
||||
if (val > 32767) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*p_s == 0) {
|
||||
return (INT16) val;
|
||||
} else {
|
||||
val *= 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_strucmp
|
||||
**
|
||||
** Description This utility function compares two strings in uppercase.
|
||||
** String p_s must be uppercase. String p_t is converted to
|
||||
** uppercase if lowercase. If p_s ends first, the substring
|
||||
** match is counted as a match.
|
||||
**
|
||||
**
|
||||
** Returns 0 if strings match, nonzero otherwise.
|
||||
**
|
||||
*******************************************************************************/
|
||||
int utl_strucmp(const char *p_s, const char *p_t)
|
||||
{
|
||||
char c;
|
||||
|
||||
while (*p_s && *p_t) {
|
||||
c = *p_t++;
|
||||
if (c >= 'a' && c <= 'z') {
|
||||
c -= 0x20;
|
||||
}
|
||||
if (*p_s++ != c) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/* if p_t hit null first, no match */
|
||||
if (*p_t == 0 && *p_s != 0) {
|
||||
return 1;
|
||||
}
|
||||
/* else p_s hit null first, count as match */
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_itoa
|
||||
**
|
||||
** Description This utility function converts a UINT16 to a string. The
|
||||
** string is NULL-terminated. The length of the string is
|
||||
** returned;
|
||||
**
|
||||
**
|
||||
** Returns Length of string.
|
||||
**
|
||||
*******************************************************************************/
|
||||
UINT8 utl_itoa(UINT16 i, char *p_s)
|
||||
{
|
||||
UINT16 j, k;
|
||||
char *p = p_s;
|
||||
BOOLEAN fill = FALSE;
|
||||
|
||||
if (i == 0) {
|
||||
/* take care of zero case */
|
||||
*p++ = '0';
|
||||
} else {
|
||||
for (j = 10000; j > 0; j /= 10) {
|
||||
k = i / j;
|
||||
i %= j;
|
||||
if (k > 0 || fill) {
|
||||
*p++ = k + '0';
|
||||
fill = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
*p = 0;
|
||||
return (UINT8) (p - p_s);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_freebuf
|
||||
**
|
||||
** Description This function calls GKI_freebuf to free the buffer passed
|
||||
** in, if buffer pointer is not NULL, and also initializes
|
||||
** buffer pointer to NULL.
|
||||
**
|
||||
**
|
||||
** Returns Nothing.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void utl_freebuf(void **p)
|
||||
{
|
||||
if (*p != NULL) {
|
||||
GKI_freebuf(*p);
|
||||
*p = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_set_device_class
|
||||
**
|
||||
** Description This function updates the local Device Class.
|
||||
**
|
||||
** Parameters:
|
||||
** p_cod - Pointer to the device class to set to
|
||||
**
|
||||
** cmd - the fields of the device class to update.
|
||||
** BTA_UTL_SET_COD_MAJOR_MINOR, - overwrite major, minor class
|
||||
** BTA_UTL_SET_COD_SERVICE_CLASS - set the bits in the input
|
||||
** BTA_UTL_CLR_COD_SERVICE_CLASS - clear the bits in the input
|
||||
** BTA_UTL_SET_COD_ALL - overwrite major, minor, set the bits in service class
|
||||
** BTA_UTL_INIT_COD - overwrite major, minor, and service class
|
||||
**
|
||||
** Returns TRUE if successful, Otherwise FALSE
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN utl_set_device_class(tBTA_UTL_COD *p_cod, UINT8 cmd)
|
||||
{
|
||||
UINT8 *dev;
|
||||
UINT16 service;
|
||||
UINT8 minor, major;
|
||||
DEV_CLASS dev_class;
|
||||
|
||||
dev = BTM_ReadDeviceClass();
|
||||
BTM_COD_SERVICE_CLASS( service, dev );
|
||||
BTM_COD_MINOR_CLASS(minor, dev );
|
||||
BTM_COD_MAJOR_CLASS(major, dev );
|
||||
|
||||
switch (cmd) {
|
||||
case BTA_UTL_SET_COD_MAJOR_MINOR:
|
||||
minor = p_cod->minor & BTM_COD_MINOR_CLASS_MASK;
|
||||
major = p_cod->major & BTM_COD_MAJOR_CLASS_MASK;
|
||||
break;
|
||||
|
||||
case BTA_UTL_SET_COD_SERVICE_CLASS:
|
||||
/* clear out the bits that is not SERVICE_CLASS bits */
|
||||
p_cod->service &= BTM_COD_SERVICE_CLASS_MASK;
|
||||
service = service | p_cod->service;
|
||||
break;
|
||||
|
||||
case BTA_UTL_CLR_COD_SERVICE_CLASS:
|
||||
p_cod->service &= BTM_COD_SERVICE_CLASS_MASK;
|
||||
service = service & (~p_cod->service);
|
||||
break;
|
||||
|
||||
case BTA_UTL_SET_COD_ALL:
|
||||
minor = p_cod->minor & BTM_COD_MINOR_CLASS_MASK;
|
||||
major = p_cod->major & BTM_COD_MAJOR_CLASS_MASK;
|
||||
p_cod->service &= BTM_COD_SERVICE_CLASS_MASK;
|
||||
service = service | p_cod->service;
|
||||
break;
|
||||
|
||||
case BTA_UTL_INIT_COD:
|
||||
minor = p_cod->minor & BTM_COD_MINOR_CLASS_MASK;
|
||||
major = p_cod->major & BTM_COD_MAJOR_CLASS_MASK;
|
||||
service = p_cod->service & BTM_COD_SERVICE_CLASS_MASK;
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* convert the fields into the device class type */
|
||||
FIELDS_TO_COD(dev_class, minor, major, service);
|
||||
|
||||
if (BTM_SetDeviceClass(dev_class) == BTM_SUCCESS) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_isintstr
|
||||
**
|
||||
** Description This utility function checks if the given string is an
|
||||
** integer string or not
|
||||
**
|
||||
**
|
||||
** Returns TRUE if successful, Otherwise FALSE
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN utl_isintstr(const char *p_s)
|
||||
{
|
||||
UINT16 i = 0;
|
||||
|
||||
for (i = 0; p_s[i] != 0; i++) {
|
||||
if (((p_s[i] < '0') || (p_s[i] > '9')) && (p_s[i] != ';')) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function utl_isdialstr
|
||||
**
|
||||
** Description This utility function checks if the given string contains
|
||||
** only dial digits or not
|
||||
**
|
||||
**
|
||||
** Returns TRUE if successful, Otherwise FALSE
|
||||
**
|
||||
*******************************************************************************/
|
||||
BOOLEAN utl_isdialstr(const char *p_s)
|
||||
{
|
||||
UINT16 i = 0;
|
||||
|
||||
for (i = 0; p_s[i] != 0; i++) {
|
||||
if (!(((p_s[i] >= '0') && (p_s[i] <= '9'))
|
||||
|| (p_s[i] == '*') || (p_s[i] == '+') || (p_s[i] == '#') || (p_s[i] == ';')
|
||||
|| ((p_s[i] >= 'A') && (p_s[i] <= 'C'))
|
||||
|| ((p_s[i] == 'p') || (p_s[i] == 'P')
|
||||
|| (p_s[i] == 'w') || (p_s[i] == 'W')))) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
91
components/bt/bluedroid/btc/core/btc_main.c
Normal file
91
components/bt/bluedroid/btc/core/btc_main.c
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.
|
||||
|
||||
#include "btc_task.h"
|
||||
#include "btc_main.h"
|
||||
#include "future.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
static future_t *main_future[BTC_MAIN_FUTURE_NUM];
|
||||
|
||||
extern int bte_main_boot_entry(void *cb);
|
||||
extern int bte_main_shutdown(void);
|
||||
|
||||
future_t **btc_main_get_future_p(btc_main_future_type_t type)
|
||||
{
|
||||
return &main_future[type];
|
||||
}
|
||||
|
||||
static void btc_sec_callback(tBTA_DM_SEC_EVT event, tBTA_DM_SEC *p_data)
|
||||
{
|
||||
switch (event) {
|
||||
case BTA_DM_ENABLE_EVT:
|
||||
future_ready(*btc_main_get_future_p(BTC_MAIN_ENABLE_FUTURE), FUTURE_SUCCESS);
|
||||
break;
|
||||
case BTA_DM_DISABLE_EVT:
|
||||
future_ready(*btc_main_get_future_p(BTC_MAIN_DISABLE_FUTURE), FUTURE_SUCCESS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bt_status_t btc_enable_bluetooth(void)
|
||||
{
|
||||
BTA_EnableBluetooth(btc_sec_callback);
|
||||
}
|
||||
|
||||
static bt_status_t btc_disable_bluetooth(void)
|
||||
{
|
||||
BTA_DisableBluetooth();
|
||||
}
|
||||
|
||||
void btc_init_callback(void)
|
||||
{
|
||||
future_ready(*btc_main_get_future_p(BTC_MAIN_INIT_FUTURE), FUTURE_SUCCESS);
|
||||
}
|
||||
|
||||
static bt_status_t btc_init_bluetooth(void)
|
||||
{
|
||||
bte_main_boot_entry(btc_init_callback);
|
||||
}
|
||||
|
||||
|
||||
static void btc_deinit_bluetooth(void)
|
||||
{
|
||||
bte_main_shutdown();
|
||||
future_ready(*btc_main_get_future_p(BTC_MAIN_DEINIT_FUTURE), FUTURE_SUCCESS);
|
||||
}
|
||||
|
||||
void btc_main_call_handler(btc_msg_t *msg)
|
||||
{
|
||||
LOG_DEBUG("%s act %d\n", __func__, msg->act);
|
||||
|
||||
switch (msg->act) {
|
||||
case BTC_MAIN_ACT_INIT:
|
||||
btc_init_bluetooth();
|
||||
break;
|
||||
case BTC_MAIN_ACT_DEINIT:
|
||||
btc_deinit_bluetooth();
|
||||
break;
|
||||
case BTC_MAIN_ACT_ENABLE:
|
||||
btc_enable_bluetooth();
|
||||
break;
|
||||
case BTC_MAIN_ACT_DISABLE:
|
||||
btc_disable_bluetooth();
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("%s UNKNOWN ACT %d\n", __func__, msg->act);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
54
components/bt/bluedroid/btc/core/btc_manage.c
Normal file
54
components/bt/bluedroid/btc/core/btc_manage.c
Normal file
@@ -0,0 +1,54 @@
|
||||
// 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 "btc_task.h"
|
||||
#include "bt_trace.h"
|
||||
#include "thread.h"
|
||||
#include "gki.h"
|
||||
#include "esp_bt_defs.h"
|
||||
#include "esp_gatt_defs.h"
|
||||
|
||||
static esp_profile_cb_t btc_profile_cb_tab[BTC_PID_NUM] = {};
|
||||
|
||||
void esp_profile_cb_reset(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < BTC_PID_NUM; i++) {
|
||||
btc_profile_cb_tab[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int btc_profile_cb_set(btc_pid_t profile_id, esp_profile_cb_t cb)
|
||||
{
|
||||
if (profile_id < 0 || profile_id >= BTC_PID_NUM) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
btc_profile_cb_tab[profile_id] = cb;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
esp_profile_cb_t btc_profile_cb_get(btc_pid_t profile_id)
|
||||
{
|
||||
if (profile_id < 0 || profile_id >= BTC_PID_NUM) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return btc_profile_cb_tab[profile_id];
|
||||
}
|
||||
|
||||
|
||||
137
components/bt/bluedroid/btc/core/btc_task.c
Normal file
137
components/bt/bluedroid/btc/core/btc_task.c
Normal file
@@ -0,0 +1,137 @@
|
||||
// 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 "btc_task.h"
|
||||
#include "bt_trace.h"
|
||||
#include "thread.h"
|
||||
#include "gki.h"
|
||||
#include "bt_defs.h"
|
||||
#include "btc_main.h"
|
||||
#include "btc_gatts.h"
|
||||
#include "btc_gattc.h"
|
||||
#include "btc_gap_ble.h"
|
||||
#include "btc_blufi_prf.h"
|
||||
#include "bta_gatt_api.h"
|
||||
|
||||
|
||||
static xTaskHandle xBtcTaskHandle = NULL;
|
||||
static xQueueHandle xBtcQueue = 0;
|
||||
|
||||
static btc_func_t profile_tab[BTC_PID_NUM] = {
|
||||
[BTC_PID_MAIN_INIT] = {btc_main_call_handler, NULL },
|
||||
[BTC_PID_GATTS] = {btc_gatts_call_handler, btc_gatts_cb_handler },
|
||||
[BTC_PID_GATTC] = {btc_gattc_call_handler, btc_gattc_cb_handler },
|
||||
[BTC_PID_GAP_BLE] = {btc_gap_ble_call_handler, btc_gap_ble_cb_handler },
|
||||
[BTC_PID_GAP_BT] = {NULL, NULL}, // {btc_gap_bt_call_handler, btc_gap_bt_cb_handler },
|
||||
[BTC_PID_SDP] = {NULL, NULL},
|
||||
[BTC_PID_BLE_HID] = {NULL, NULL},
|
||||
[BTC_PID_BT_HID] = {NULL, NULL},
|
||||
[BTC_PID_SPP] = {NULL, NULL},
|
||||
[BTC_PID_SPPLIKE] = {NULL, NULL},
|
||||
[BTC_PID_BLUFI] = {btc_blufi_call_handler, btc_blufi_cb_handler },
|
||||
};
|
||||
|
||||
/*****************************************************************************
|
||||
**
|
||||
** Function btc_task
|
||||
**
|
||||
** Description Process profile Task Thread.
|
||||
******************************************************************************/
|
||||
static void btc_task(void *arg)
|
||||
{
|
||||
btc_msg_t msg;
|
||||
|
||||
for (;;) {
|
||||
if (pdTRUE == xQueueReceive(xBtcQueue, &msg, (portTickType)portMAX_DELAY)) {
|
||||
LOG_DEBUG("%s msg %u %u %u %08x\n", __func__, msg.sig, msg.pid, msg.act, msg.arg);
|
||||
switch (msg.sig) {
|
||||
case BTC_SIG_API_CALL:
|
||||
profile_tab[msg.pid].btc_call(&msg);
|
||||
break;
|
||||
case BTC_SIG_API_CB:
|
||||
profile_tab[msg.pid].btc_cb(&msg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (msg.arg) {
|
||||
GKI_freebuf(msg.arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bt_status_t btc_task_post(btc_msg_t *msg)
|
||||
{
|
||||
if (msg == NULL) {
|
||||
return BT_STATUS_PARM_INVALID;
|
||||
}
|
||||
|
||||
if (xQueueSend(xBtcQueue, msg, 10 / portTICK_RATE_MS) != pdTRUE) {
|
||||
LOG_ERROR("Btc Post failed\n");
|
||||
return BT_STATUS_BUSY;
|
||||
}
|
||||
|
||||
return BT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg_deep_copy_t copy_func)
|
||||
{
|
||||
btc_msg_t lmsg;
|
||||
|
||||
if (msg == NULL) {
|
||||
return BT_STATUS_PARM_INVALID;
|
||||
}
|
||||
|
||||
LOG_DEBUG("%s msg %u %u %u %p\n", __func__, msg->sig, msg->pid, msg->act, arg);
|
||||
|
||||
memcpy(&lmsg, msg, sizeof(btc_msg_t));
|
||||
if (arg) {
|
||||
lmsg.arg = (void *)GKI_getbuf(arg_len);
|
||||
memset(lmsg.arg, 0x00, arg_len); //important, avoid arg which have no length
|
||||
if (lmsg.arg == NULL) {
|
||||
return BT_STATUS_NOMEM;
|
||||
}
|
||||
memcpy(lmsg.arg, arg, arg_len);
|
||||
if (copy_func) {
|
||||
copy_func(&lmsg, lmsg.arg, arg);
|
||||
}
|
||||
} else {
|
||||
lmsg.arg = NULL;
|
||||
}
|
||||
|
||||
return btc_task_post(&lmsg);
|
||||
}
|
||||
|
||||
|
||||
int btc_init(void)
|
||||
{
|
||||
xBtcQueue = xQueueCreate(BTC_TASK_QUEUE_NUM, sizeof(btc_msg_t));
|
||||
xTaskCreate(btc_task, "Btc_task", BTC_TASK_STACK_SIZE, NULL, BTC_TASK_PRIO, &xBtcTaskHandle);
|
||||
|
||||
/* TODO: initial the profile_tab */
|
||||
|
||||
return BT_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void btc_deinit(void)
|
||||
{
|
||||
vTaskDelete(xBtcTaskHandle);
|
||||
vQueueDelete(xBtcQueue);
|
||||
|
||||
xBtcTaskHandle = NULL;
|
||||
xBtcQueue = 0;
|
||||
}
|
||||
64
components/bt/bluedroid/btc/include/btc_main.h
Normal file
64
components/bt/bluedroid/btc/include/btc_main.h
Normal file
@@ -0,0 +1,64 @@
|
||||
// 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 __BTC_BT_MAIN_H__
|
||||
#define __BTC_BT_MAIN_H__
|
||||
|
||||
#include "future.h"
|
||||
#include "bt_types.h"
|
||||
#include "bta_api.h"
|
||||
#include "btc_main.h"
|
||||
#include "btc_task.h"
|
||||
|
||||
typedef enum {
|
||||
BTC_MAIN_ACT_INIT = 0,
|
||||
BTC_MAIN_ACT_DEINIT,
|
||||
BTC_MAIN_ACT_ENABLE,
|
||||
BTC_MAIN_ACT_DISABLE,
|
||||
} btc_main_act_t;
|
||||
|
||||
typedef enum {
|
||||
BTC_MAIN_INIT_FUTURE = 0,
|
||||
BTC_MAIN_DEINIT_FUTURE,
|
||||
BTC_MAIN_ENABLE_FUTURE,
|
||||
BTC_MAIN_DISABLE_FUTURE,
|
||||
BTC_MAIN_FUTURE_NUM,
|
||||
} btc_main_future_type_t;
|
||||
|
||||
future_t **btc_main_get_future_p(btc_main_future_type_t type);
|
||||
|
||||
#if 0
|
||||
typedef union {
|
||||
struct btc_main_init_args {
|
||||
future_t *future;
|
||||
} init;
|
||||
struct btc_main_deinit_args {
|
||||
future_t *future;
|
||||
} deinit;
|
||||
struct btc_main_init_args {
|
||||
future_t *future;
|
||||
} enable;
|
||||
struct btc_main_init_args {
|
||||
future_t *future;
|
||||
} disable;
|
||||
} btc_main_args_t;
|
||||
|
||||
bt_status_t btc_enable_bluetooth(future_t *future);
|
||||
void btc_disable_bluetooth(future_t *future);
|
||||
bt_status_t btc_init_bluetooth(future_t *future);
|
||||
void btc_deinit_bluetooth(future_t *future);
|
||||
#endif
|
||||
|
||||
void btc_main_call_handler(btc_msg_t *msg);
|
||||
#endif /* __BTC_BT_MAIN_H__ */
|
||||
28
components/bt/bluedroid/btc/include/btc_manage.h
Normal file
28
components/bt/bluedroid/btc/include/btc_manage.h
Normal file
@@ -0,0 +1,28 @@
|
||||
// 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 __BTC_MANAGE_H__
|
||||
#define __BTC_MANAGE_H__
|
||||
|
||||
#include "bta_api.h"
|
||||
#include "btc_task.h"
|
||||
#include "esp_bt_defs.h"
|
||||
|
||||
/* reset gatt callback table */
|
||||
void esp_profile_cb_reset(void);
|
||||
|
||||
int btc_profile_cb_set(btc_pid_t profile_id, esp_profile_cb_t cb);
|
||||
esp_profile_cb_t btc_profile_cb_get(btc_pid_t profile_id);
|
||||
|
||||
#endif /* __BTC_MANAGE_H__ */
|
||||
63
components/bt/bluedroid/btc/include/btc_task.h
Normal file
63
components/bt/bluedroid/btc/include/btc_task.h
Normal file
@@ -0,0 +1,63 @@
|
||||
// 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 __BTC_TASK_H__
|
||||
#define __BTC_TASK_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "bt_defs.h"
|
||||
#include "thread.h"
|
||||
|
||||
typedef struct btc_msg {
|
||||
uint8_t sig; //event signal
|
||||
uint8_t aid; //application id
|
||||
uint8_t pid; //profile id
|
||||
uint8_t act; //profile action, defined in seprerate header files
|
||||
void *arg; //param for btc function or function param
|
||||
} btc_msg_t;
|
||||
|
||||
typedef enum {
|
||||
BTC_SIG_API_CALL = 0, // APP TO STACK
|
||||
BTC_SIG_API_CB, // STACK TO APP
|
||||
BTC_SIG_NUM,
|
||||
} btc_sig_t; //btc message type
|
||||
|
||||
typedef enum {
|
||||
BTC_PID_MAIN_INIT = 0,
|
||||
BTC_PID_GATTS,
|
||||
BTC_PID_GATTC,
|
||||
BTC_PID_GAP_BLE,
|
||||
BTC_PID_GAP_BT,
|
||||
BTC_PID_SDP,
|
||||
BTC_PID_BLE_HID,
|
||||
BTC_PID_BT_HID,
|
||||
BTC_PID_SPP,
|
||||
BTC_PID_SPPLIKE,
|
||||
BTC_PID_BLUFI,
|
||||
BTC_PID_NUM,
|
||||
} btc_pid_t; //btc profile id
|
||||
|
||||
typedef struct {
|
||||
void (* btc_call)(btc_msg_t *msg);
|
||||
void (* btc_cb)(btc_msg_t *msg);
|
||||
} btc_func_t;
|
||||
|
||||
typedef void (* btc_arg_deep_copy_t)(btc_msg_t *msg, void *dst, void *src);
|
||||
|
||||
bt_status_t btc_transfer_context(btc_msg_t *msg, void *arg, int arg_len, btc_arg_deep_copy_t copy_func);
|
||||
|
||||
int btc_init(void);
|
||||
void btc_deinit(void);
|
||||
|
||||
#endif /* __BTC_TASK_H__ */
|
||||
342
components/bt/bluedroid/btc/profile/esp/ble_button/button_pro.c
Normal file
342
components/bt/bluedroid/btc/profile/esp/ble_button/button_pro.c
Normal file
@@ -0,0 +1,342 @@
|
||||
// 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 <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#include "bt_target.h"
|
||||
#include "bt_trace.h"
|
||||
#include "bt_types.h"
|
||||
#include "gatt_api.h"
|
||||
#include "bta_api.h"
|
||||
#include "bta_gatt_api.h"
|
||||
#include "bta_gatts_int.h"
|
||||
#include "button_pro.h"
|
||||
|
||||
#include "prf_defs.h"
|
||||
|
||||
#if (BUT_PROFILE_CFG)
|
||||
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
||||
button_env_cb_t button_cb_env;
|
||||
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
static void button_profile_cb(esp_gatts_evt_t event, esp_gatts_t *p_data);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function button_profile_cb
|
||||
**
|
||||
** Description the callback function after the profile has been register to the BTA manager module
|
||||
**
|
||||
** Returns NULL
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void button_profile_cb(esp_gatts_evt_t event, esp_gatts_t *p_data)
|
||||
{
|
||||
esp_gatts_rsp_t rsp;
|
||||
esp_bt_uuid_t uuid = {LEN_UUID_16, {ATT_SVC_BUTTON}};
|
||||
but_inst_t *p_inst = &button_cb_env.button_inst;
|
||||
uint8_t net_event = 0xff;
|
||||
uint8_t len = 0;
|
||||
uint8_t *p_rec_data = NULL;
|
||||
//LOG_ERROR("p_data->status = %x\n",p_data->status);
|
||||
//if(p_data->status != BTA_GATT_OK){
|
||||
// LOG_ERROR("button profile register failed\n");
|
||||
// return;
|
||||
//}
|
||||
LOG_ERROR("button profile cb event = %x\n", event);
|
||||
switch (event) {
|
||||
case ESP_GATTS_REG_EVT:
|
||||
|
||||
LOG_ERROR("p_data->reg_oper.status = %x\n", p_data->reg_oper.status);
|
||||
LOG_ERROR("(p_data->reg_oper.uuid.uu.uuid16=%x\n", p_data->reg_oper.uuid.uu.uuid16);
|
||||
if (p_data->reg_oper.status != BTA_GATT_OK) {
|
||||
LOG_ERROR("button profile register failed\n");
|
||||
}
|
||||
button_cb_env.gatt_if = p_data->reg_oper.server_if;
|
||||
button_cb_env.enabled = true;
|
||||
//button_cb_env.button_inst.app_id = p_data->reg_oper.uuid;
|
||||
//create the button service to the service data base.
|
||||
if (p_data->reg_oper.uuid.uu.uuid16 == ATT_SVC_BUTTON) {
|
||||
Button_CreateService();
|
||||
}
|
||||
break;
|
||||
case ESP_GATTS_READ_EVT:
|
||||
//tBTA_GATTS_RSP rsp;
|
||||
memset(&rsp, 0, sizeof(tBTA_GATTS_API_RSP));
|
||||
rsp.attr_value.handle = p_data->req_data.p_data->read_req.handle;
|
||||
rsp.attr_value.len = 2;
|
||||
esp_ble_gatts_send_rsp(p_data->req_data.conn_id, p_data->req_data.trans_id,
|
||||
p_data->req_data.status, &rsp);
|
||||
break;
|
||||
case ESP_GATTS_WRITE_EVT:
|
||||
esp_ble_gatts_send_rsp(p_data->req_data.conn_id, p_data->req_data.trans_id,
|
||||
p_data->req_data.status, NULL);
|
||||
LOG_ERROR("Received button data:");
|
||||
for (int i = 0; i < p_data->req_data.p_data->write_req.len; i++) {
|
||||
LOG_ERROR("%x", p_data->req_data.p_data->write_req.value[i]);
|
||||
}
|
||||
LOG_ERROR("\n");
|
||||
if (p_data->req_data.p_data->write_req.handle == button_cb_env.button_inst.but_wirt_hdl) {
|
||||
|
||||
p_rec_data = &p_data->req_data.p_data->write_req.value[0];
|
||||
// button_msg_notify(len,p_rec_data);
|
||||
(*p_inst->p_cback)(button_cb_env.button_inst.app_id, net_event, len, p_rec_data);
|
||||
|
||||
}
|
||||
break;
|
||||
case ESP_GATTS_CFM_EVT:
|
||||
|
||||
break;
|
||||
case ESP_GATTS_CREATE_EVT:
|
||||
//tBT_UUID uuid_butt_write;
|
||||
uuid.uu.uuid16 = ATT_CHAR_BUTTON_WIT;
|
||||
//tBTA_GATT_PERM perm = (GATT_PERM_WRITE|GATT_PERM_READ);
|
||||
//tBTA_GATT_CHAR_PROP prop = (GATT_CHAR_PROP_BIT_READ|GATT_CHAR_PROP_BIT_WRITE);
|
||||
//uuid = {LEN_UUID_16, {ATT_SVC_BUTTON}};
|
||||
button_cb_env.clcb.cur_srvc_id = p_data->create.service_id;
|
||||
button_cb_env.is_primery = p_data->create.is_primary;
|
||||
//uuid = {LEN_UUID_16, {ATT_CHAR_BUTTON_WIT}};
|
||||
//start the button service after created
|
||||
esp_ble_gatts_start_srvc(p_data->create.service_id);
|
||||
//add the frist button characteristic --> write characteristic
|
||||
esp_ble_gatts_add_char(button_cb_env.clcb.cur_srvc_id, &uuid,
|
||||
(GATT_PERM_WRITE | GATT_PERM_READ),
|
||||
(GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_WRITE));
|
||||
break;
|
||||
|
||||
case ESP_GATTS_ADD_CHAR_EVT:
|
||||
if (p_data->add_result.char_uuid.uu.uuid16 == ATT_CHAR_BUTTON_WIT) {
|
||||
uuid.uu.uuid16 = ATT_CHAR_BUTTON_NTF;
|
||||
//tBTA_GATT_PERM perm = GATT_PERM_READ;
|
||||
tBTA_GATT_CHAR_PROP prop = (GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
|
||||
//save the att handle to the env
|
||||
button_cb_env.button_inst.but_wirt_hdl = p_data->add_result.attr_id;
|
||||
//add the frist button characteristic --> Notify characteristic
|
||||
esp_ble_gatts_add_char(button_cb_env.clcb.cur_srvc_id, &uuid,
|
||||
GATT_PERM_READ, (GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY));
|
||||
} else if (p_data->add_result.char_uuid.uu.uuid16 == ATT_CHAR_BUTTON_NTF) { // add the gattc config descriptor to the notify charateristic
|
||||
//tBTA_GATT_PERM perm = (GATT_PERM_WRITE|GATT_PERM_WRITE);
|
||||
uuid.uu.uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG;
|
||||
button_cb_env.button_inst.but_ntf_hdl = p_data->add_result.attr_id;
|
||||
esp_ble_gatts_add_char_descr (button_cb_env.clcb.cur_srvc_id,
|
||||
(GATT_PERM_WRITE | GATT_PERM_WRITE),
|
||||
&uuid);
|
||||
}
|
||||
|
||||
break;
|
||||
case ESP_GATTS_ADD_CHAR_DESCR_EVT:
|
||||
if (p_data->add_result.char_uuid.uu.uuid16 == GATT_UUID_CHAR_CLIENT_CONFIG) {
|
||||
button_cb_env.button_inst.but_cfg_hdl = p_data->add_result.attr_id;
|
||||
}
|
||||
///Start advertising
|
||||
LOG_ERROR("\n*******Start sent the ADV.*************\n");
|
||||
//esp_ble_start_advertising (&adv_params);
|
||||
//BTA_GATTS_Listen(button_cb_env.gatt_if, true, NULL);
|
||||
break;
|
||||
case ESP_GATTS_CONNECT_EVT:
|
||||
LOG_ERROR("############BUTTON CONNCET EVT################\n");
|
||||
//esp_ble_stop_advertising();
|
||||
//set the connection flag to true
|
||||
button_env_clcb_alloc(p_data->conn.conn_id, p_data->conn.remote_bda);
|
||||
break;
|
||||
case ESP_GATTS_DISCONNECT_EVT:
|
||||
//set the connection flag to true
|
||||
button_cb_env.clcb.connected = false;
|
||||
break;
|
||||
case ESP_GATTS_OPEN_EVT:
|
||||
///stop the advertising after connected
|
||||
|
||||
break;
|
||||
case ESP_GATTS_CLOSE_EVT:
|
||||
if (button_cb_env.clcb.connected && (button_cb_env.clcb.conn_id == p_data->conn.conn_id)) {
|
||||
//set the connection channal congested flag to true
|
||||
button_cb_env.clcb.congest = p_data->congest.congested;
|
||||
}
|
||||
break;
|
||||
case ESP_GATTS_CONGEST_EVT:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function Button_CreateService
|
||||
**
|
||||
** Description Create a Service for the button profile
|
||||
**
|
||||
** Returns NULL
|
||||
**
|
||||
*******************************************************************************/
|
||||
void Button_CreateService(void)
|
||||
{
|
||||
esp_gatts_if_t server_if ;
|
||||
esp_bt_uuid_t uuid = {LEN_UUID_16, {ATT_SVC_BUTTON}};
|
||||
uint16_t num_handle = KEY_IDX_NB;
|
||||
uint8_t inst = 0x00;
|
||||
server_if = button_cb_env.gatt_if;
|
||||
button_cb_env.inst_id = inst;
|
||||
//if(!button_cb_env.enabled)
|
||||
//{
|
||||
// LOG_ERROR("button service added error.");
|
||||
//}
|
||||
esp_ble_gatts_create_srvc(server_if, &uuid, inst, num_handle, true);
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function button_env_clcb_alloc
|
||||
**
|
||||
** Description The function allocates a GATT profile connection link control block
|
||||
**
|
||||
** Returns NULL if not found. Otherwise pointer to the connection link block.
|
||||
**
|
||||
*******************************************************************************/
|
||||
but_clcb_t *button_env_clcb_alloc (uint16_t conn_id, BD_ADDR remote_bda)
|
||||
{
|
||||
but_clcb_t *p_clcb = NULL;
|
||||
p_clcb = &button_cb_env.clcb;
|
||||
|
||||
if (!p_clcb->in_use) {
|
||||
p_clcb->in_use = TRUE;
|
||||
p_clcb->conn_id = conn_id;
|
||||
LOG_ERROR("p_clcb->conn_id = %x\n", conn_id);
|
||||
p_clcb->connected = TRUE;
|
||||
memcpy(p_clcb->remote_bda, remote_bda, BD_ADDR_LEN);
|
||||
}
|
||||
|
||||
return p_clcb;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function button_env_find_conn_id_by_bd_adddr
|
||||
**
|
||||
** Description The function searches all LCB with macthing bd address
|
||||
**
|
||||
** Returns total number of clcb found.
|
||||
**
|
||||
*******************************************************************************/
|
||||
uint16_t button_env_find_conn_id_by_bd_adddr(BD_ADDR remote_bda)
|
||||
{
|
||||
uint8_t i_clcb;
|
||||
but_clcb_t *p_clcb = NULL;
|
||||
|
||||
for (i_clcb = 0, p_clcb = &button_cb_env.clcb; i_clcb < BUTT_MAX_APPS; i_clcb++, p_clcb++) {
|
||||
if (p_clcb->in_use && p_clcb->connected && memcmp(p_clcb->remote_bda, remote_bda, BD_ADDR_LEN)) {
|
||||
return p_clcb->conn_id;
|
||||
}
|
||||
}
|
||||
|
||||
return GATT_INVALID_CONN_ID;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function button_env_clcb_dealloc
|
||||
**
|
||||
** Description The function deallocates a GATT profile connection link control block
|
||||
**
|
||||
** Returns True the deallocation is successful
|
||||
**
|
||||
*******************************************************************************/
|
||||
|
||||
BOOLEAN button_env_clcb_dealloc(uint16_t conn_id)
|
||||
{
|
||||
uint16_t i_clcb = 0;
|
||||
but_clcb_t *p_clcb = NULL;
|
||||
|
||||
for (i_clcb = 0, p_clcb = &button_cb_env.clcb; i_clcb < 1; i_clcb++, p_clcb++) {
|
||||
if (p_clcb->in_use && p_clcb->connected && (p_clcb->conn_id == conn_id)) {
|
||||
memset(p_clcb, 0, sizeof(but_clcb_t));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function button_init
|
||||
**
|
||||
** Description Initializa the GATT Service for button profiles.
|
||||
**
|
||||
*******************************************************************************/
|
||||
esp_gatt_status_t button_init (but_prf_cb_t call_back)
|
||||
{
|
||||
tBT_UUID app_uuid = {LEN_UUID_16, {ATT_SVC_BUTTON}};
|
||||
|
||||
LOG_ERROR("\n=============================button_init==============================================\n");
|
||||
if (button_cb_env.enabled) {
|
||||
LOG_ERROR("button svc already initaliezd\n");
|
||||
return ESP_GATT_ERROR;
|
||||
} else {
|
||||
memset(&button_cb_env, 0, sizeof(button_env_cb_t));
|
||||
}
|
||||
|
||||
|
||||
if (call_back != NULL) {
|
||||
button_cb_env.button_inst.p_cback = call_back;
|
||||
}
|
||||
|
||||
|
||||
/* register the button profile to the BTA_GATTS module*/
|
||||
esp_ble_gatts_app_register(&app_uuid, button_profile_cb);
|
||||
|
||||
button_cb_env.enabled = TRUE;
|
||||
|
||||
return ESP_GATT_OK;
|
||||
}
|
||||
|
||||
void button_disable(uint16_t connid)
|
||||
{
|
||||
button_env_clcb_dealloc(connid);
|
||||
}
|
||||
|
||||
|
||||
void button_msg_notify(uint16_t len, uint8_t *button_msg)
|
||||
{
|
||||
BOOLEAN conn_status = button_cb_env.clcb.connected;
|
||||
uint16_t conn_id = button_cb_env.clcb.conn_id;
|
||||
uint16_t attr_id = button_cb_env.button_inst.but_ntf_hdl;
|
||||
//notify rsp==false; indicate rsp==true.
|
||||
BOOLEAN rsp = false;
|
||||
if (!conn_status && button_cb_env.clcb.congest) {
|
||||
LOG_ERROR("the conneciton for button profile has been loss\n");
|
||||
return;
|
||||
}
|
||||
|
||||
esp_ble_gatts_hdl_val_indica (conn_id, attr_id, len,
|
||||
button_msg, rsp);
|
||||
}
|
||||
|
||||
#endif ///BUT_PROFILE_CFG
|
||||
164
components/bt/bluedroid/btc/profile/esp/blufi/blufi_adv.c
Normal file
164
components/bt/bluedroid/btc/profile/esp/blufi/blufi_adv.c
Normal file
@@ -0,0 +1,164 @@
|
||||
// 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 "blufi_adv.h"
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BlufiConfigadvData
|
||||
**
|
||||
** Description This function is called to override the BTA default ADV parameters.
|
||||
**
|
||||
** adv_data: Pointer to User defined ADV data structure. This
|
||||
** memory space can not be freed until p_adv_data_cback
|
||||
** is received.
|
||||
** p_adv_data_cback: set adv data complete callback.
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BlufiBleConfigadvData(tBLUFI_BLE_ADV_DATA *adv_data,
|
||||
tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback)
|
||||
{
|
||||
tBTA_BLE_AD_MASK data_mask = 0;
|
||||
if (adv_data->adv_name != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_DEV_NAME;
|
||||
BTA_DmSetDeviceName(adv_data->adv_name);
|
||||
}
|
||||
if (adv_data->ble_adv_data.int_range.low != 0 ||
|
||||
adv_data->ble_adv_data.int_range.hi != 0) {
|
||||
data_mask |= BTM_BLE_AD_BIT_INT_RANGE;
|
||||
}
|
||||
|
||||
if (adv_data->ble_adv_data.p_manu != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_MANU;
|
||||
}
|
||||
|
||||
if (adv_data->ble_adv_data.p_services != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_SERVICE;
|
||||
}
|
||||
|
||||
if (adv_data->ble_adv_data.p_service_32b != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_SERVICE_32;
|
||||
}
|
||||
|
||||
if (adv_data->ble_adv_data.p_services_128b != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_SERVICE_128;
|
||||
}
|
||||
|
||||
if (adv_data->ble_adv_data.p_sol_services != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_SERVICE_SOL;
|
||||
}
|
||||
|
||||
if (adv_data->ble_adv_data.p_sol_service_32b != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_SERVICE_32SOL;
|
||||
}
|
||||
|
||||
if (adv_data->ble_adv_data.p_sol_service_128b != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_SERVICE_128SOL;
|
||||
}
|
||||
|
||||
if (adv_data->ble_adv_data.p_service_data != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_SERVICE_DATA;
|
||||
}
|
||||
|
||||
if (adv_data->ble_adv_data.appearance != 0) {
|
||||
data_mask |= BTM_BLE_AD_BIT_APPEARANCE;
|
||||
}
|
||||
|
||||
if (adv_data->ble_adv_data.p_proprietary != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_PROPRIETARY;
|
||||
}
|
||||
|
||||
if (adv_data->ble_adv_data.tx_power != 0) {
|
||||
data_mask |= BTM_BLE_AD_BIT_TX_PWR;
|
||||
}
|
||||
|
||||
BTA_DmBleSetAdvConfig(data_mask, &(adv_data->ble_adv_data), p_adv_data_cback);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BLUFI_BleSetScanRsp
|
||||
**
|
||||
** Description This function is called to override the app scan response.
|
||||
**
|
||||
** Parameters Pointer to User defined ADV data structure
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BlufiBleSetScanRsp(tBLUFI_BLE_ADV_DATA *scan_rsp_data,
|
||||
tBTA_SET_ADV_DATA_CMPL_CBACK *p_scan_rsp_data_cback)
|
||||
{
|
||||
tBTA_BLE_AD_MASK data_mask = 0;
|
||||
if (scan_rsp_data->adv_name != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_DEV_NAME;
|
||||
BTA_DmSetDeviceName(scan_rsp_data->adv_name);
|
||||
}
|
||||
if (scan_rsp_data->ble_adv_data.int_range.low != 0 ||
|
||||
scan_rsp_data->ble_adv_data.int_range.hi != 0) {
|
||||
data_mask |= BTM_BLE_AD_BIT_INT_RANGE;
|
||||
}
|
||||
|
||||
if (scan_rsp_data->ble_adv_data.p_manu != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_MANU;
|
||||
}
|
||||
|
||||
if (scan_rsp_data->ble_adv_data.p_services != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_SERVICE;
|
||||
}
|
||||
|
||||
if (scan_rsp_data->ble_adv_data.p_service_32b != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_SERVICE_32;
|
||||
}
|
||||
|
||||
if (scan_rsp_data->ble_adv_data.p_services_128b != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_SERVICE_128;
|
||||
}
|
||||
|
||||
if (scan_rsp_data->ble_adv_data.p_sol_services != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_SERVICE_SOL;
|
||||
}
|
||||
|
||||
if (scan_rsp_data->ble_adv_data.p_sol_service_32b != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_SERVICE_32SOL;
|
||||
}
|
||||
|
||||
if (scan_rsp_data->ble_adv_data.p_sol_service_128b != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_SERVICE_128SOL;
|
||||
}
|
||||
|
||||
if (scan_rsp_data->ble_adv_data.p_service_data != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_SERVICE_DATA;
|
||||
}
|
||||
|
||||
if (scan_rsp_data->ble_adv_data.appearance != 0) {
|
||||
data_mask |= BTM_BLE_AD_BIT_APPEARANCE;
|
||||
}
|
||||
|
||||
if (scan_rsp_data->ble_adv_data.p_proprietary != NULL) {
|
||||
data_mask |= BTM_BLE_AD_BIT_PROPRIETARY;
|
||||
}
|
||||
|
||||
if (scan_rsp_data->ble_adv_data.tx_power != 0) {
|
||||
data_mask |= BTM_BLE_AD_BIT_TX_PWR;
|
||||
}
|
||||
|
||||
BTA_DmBleSetScanRsp(data_mask, &(scan_rsp_data->ble_adv_data), p_scan_rsp_data_cback);
|
||||
}
|
||||
|
||||
|
||||
380
components/bt/bluedroid/btc/profile/esp/blufi/blufi_prf.c
Normal file
380
components/bt/bluedroid/btc/profile/esp/blufi/blufi_prf.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 <stdint.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#include "bt_target.h"
|
||||
#include "bt_trace.h"
|
||||
#include "bt_types.h"
|
||||
#include "gatt_api.h"
|
||||
#include "bta_api.h"
|
||||
#include "bta_gatt_api.h"
|
||||
#include "bta_gatts_int.h"
|
||||
|
||||
#include "btc_blufi_prf.h"
|
||||
#include "btc_task.h"
|
||||
#include "btc_manage.h"
|
||||
|
||||
#include "blufi_adv.h"
|
||||
#include "blufi_int.h"
|
||||
|
||||
static uint8_t *success_msg = "BLUFI_CONFIG_OK";
|
||||
static uint8_t *failed_msg = "BLUFI_CONFIG_FAILED";
|
||||
|
||||
#define BTC_BLUFI_CB_TO_APP(_event, _param) ((esp_profile_cb_t)btc_profile_cb_get(BTC_PID_BLUFI))(_event, _param)
|
||||
|
||||
#define BT_BD_ADDR_STR "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||
#define BT_BD_ADDR_HEX(addr) addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
|
||||
|
||||
|
||||
UINT16 esp32_uuid = SVC_BLUFI_UUID;
|
||||
UINT8 esp32_manu[17] = {0xff, 0x20, 0x14, 0x07, 0x22, 0x00, 0x02, 0x5B, 0x00, 0x33, 0x49, 0x31, 0x30, 0x4a, 0x30, 0x30, 0x31};
|
||||
tBTA_BLE_MANU p_esp32_manu = {sizeof(esp32_manu), esp32_manu}; /* manufacturer data */
|
||||
|
||||
tBTA_BLE_SERVICE esp32_service = {
|
||||
0x01, //only one service in the ijiazu button profile
|
||||
false,
|
||||
&esp32_uuid
|
||||
}; /* 16 bits services */
|
||||
|
||||
|
||||
tBLUFI_BLE_ADV_DATA esp32_adv_data[ADV_SCAN_IDX_MAX] = {
|
||||
[BLE_ADV_DATA_IDX] = {
|
||||
.adv_name = "Espressif_008",
|
||||
{
|
||||
{0, 0},
|
||||
NULL, //no manufature data to be setting in the esp32 adervetisiing datas
|
||||
&esp32_service,
|
||||
NULL, //the 128 bits service uuid set to null(not used)
|
||||
NULL, //the 32 bits Service UUID set to null(not used)
|
||||
NULL, //16 bits services Solicitation UUIDs set to null(not used)
|
||||
NULL, //List of 32 bit Service Solicitation UUIDs set to null(not used)
|
||||
NULL, //List of 128 bit Service Solicitation UUIDs set to null(not used)
|
||||
NULL, //proprietary data set to null(not used)
|
||||
NULL, //service data set not null(no service data to be sent)
|
||||
0x0200, //device type : generic display
|
||||
BTA_DM_GENERAL_DISC, // General discoverable.
|
||||
0xFE //the tx power value,defult value is 0
|
||||
},
|
||||
},
|
||||
|
||||
[BLE_SCAN_RSP_DATA_IDX] = {
|
||||
.adv_name = NULL,
|
||||
{
|
||||
{0, 0},
|
||||
&p_esp32_manu,
|
||||
NULL,
|
||||
NULL, //the 128 bits service uuid set to null(not used)
|
||||
NULL, //the 32 bits Service UUID set to null(not used)
|
||||
NULL, //16 bits services Solicitation UUIDs set to null(not used)
|
||||
NULL, //List of 32 bit Service Solicitation UUIDs set to null(not used)
|
||||
NULL, //List of 128 bit Service Solicitation UUIDs set to null(not used)
|
||||
NULL, //proprietary data set to null(not used)
|
||||
NULL, //service data set not null(no service data to be sent)
|
||||
0x0000, //device type : generic display
|
||||
0x00, // General discoverable.
|
||||
0x00
|
||||
}, //the tx power value,defult value is 0
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
static tBLUFI_CB_ENV blufi_cb_env;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function blufi_create_service
|
||||
**
|
||||
** Description Create a Service for the blufi profile
|
||||
**
|
||||
** Returns NULL
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void blufi_create_service(void)
|
||||
{
|
||||
tBTA_GATTS_IF server_if ;
|
||||
tBT_UUID uuid = {LEN_UUID_16, {SVC_BLUFI_UUID}};
|
||||
UINT16 num_handle = BLUFI_HDL_NUM;
|
||||
UINT8 inst = 0x00;
|
||||
server_if = blufi_cb_env.gatt_if;
|
||||
blufi_cb_env.inst_id = inst;
|
||||
if (!blufi_cb_env.enabled) {
|
||||
LOG_ERROR("blufi service added error.");
|
||||
return;
|
||||
}
|
||||
BTA_GATTS_CreateService(server_if, &uuid, inst, num_handle, true);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function blufi_profile_cb
|
||||
**
|
||||
** Description the callback function after the profile has been register to the BTA manager module
|
||||
**
|
||||
** Returns NULL
|
||||
**
|
||||
*******************************************************************************/
|
||||
static void blufi_profile_cb(tBTA_GATTS_EVT event, tBTA_GATTS *p_data)
|
||||
{
|
||||
tBTA_GATTS_RSP rsp;
|
||||
tBT_UUID uuid = {LEN_UUID_16, {SVC_BLUFI_UUID}};
|
||||
UINT8 len = 0;
|
||||
UINT8 *p_rec_data = NULL;
|
||||
tBTA_GATT_STATUS status;
|
||||
|
||||
LOG_DEBUG("blufi profile cb event = %x\n", event);
|
||||
switch (event) {
|
||||
case BTA_GATTS_REG_EVT:
|
||||
status = p_data->reg_oper.status;
|
||||
|
||||
LOG_DEBUG("p_data->reg_oper.status = %x\n", p_data->reg_oper.status);
|
||||
LOG_DEBUG("(p_data->reg_oper.uuid.uu.uuid16=%x\n", p_data->reg_oper.uuid.uu.uuid16);
|
||||
if (p_data->reg_oper.status != BTA_GATT_OK) {
|
||||
LOG_ERROR("blufi profile register failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
blufi_cb_env.gatt_if = p_data->reg_oper.server_if;
|
||||
blufi_cb_env.enabled = true;
|
||||
LOG_DEBUG("register complete: event=%d, status=%d, server_if=%d\n",
|
||||
event, status, blufi_cb_env.gatt_if);
|
||||
|
||||
LOG_DEBUG("set advertising parameters\n");
|
||||
//set the advertising data to the btm layer
|
||||
BlufiBleConfigadvData(&esp32_adv_data[BLE_ADV_DATA_IDX], NULL);
|
||||
//set the adversting data to the btm layer
|
||||
BlufiBleSetScanRsp(&esp32_adv_data[BLE_SCAN_RSP_DATA_IDX], NULL);
|
||||
BTA_GATTS_Listen(blufi_cb_env.gatt_if, true, NULL);
|
||||
|
||||
//create the blufi service to the service data base.
|
||||
if (p_data->reg_oper.uuid.uu.uuid16 == SVC_BLUFI_UUID) {
|
||||
blufi_create_service();
|
||||
}
|
||||
break;
|
||||
case BTA_GATTS_READ_EVT:
|
||||
memset(&rsp, 0, sizeof(tBTA_GATTS_API_RSP));
|
||||
rsp.attr_value.handle = p_data->req_data.p_data->read_req.handle;
|
||||
rsp.attr_value.len = 2;
|
||||
//rsp.attr_value.value[0] = 0xde;
|
||||
//rsp.attr_value.value[1] = 0xed;
|
||||
//rsp.attr_value.value[2] = 0xbe;
|
||||
//rsp.attr_value.value[3] = 0xef;
|
||||
BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id,
|
||||
p_data->req_data.status, &rsp);
|
||||
break;
|
||||
case BTA_GATTS_WRITE_EVT:
|
||||
BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id,
|
||||
p_data->req_data.status, NULL);
|
||||
|
||||
LOG_DEBUG("Received blufi data:");
|
||||
for (int i = 0; i < p_data->req_data.p_data->write_req.len; i++) {
|
||||
LOG_DEBUG("%x", p_data->req_data.p_data->write_req.value[i]);
|
||||
}
|
||||
LOG_DEBUG("\n");
|
||||
|
||||
if (p_data->req_data.p_data->write_req.handle == blufi_cb_env.blufi_inst.blufi_hdl) {
|
||||
btc_msg_t msg;
|
||||
struct blufi_recv_evt_param recv_data;
|
||||
|
||||
memset(&recv_data, 0x00, sizeof(struct blufi_recv_evt_param));
|
||||
|
||||
p_rec_data = &p_data->req_data.p_data->write_req.value[0];
|
||||
recv_data.data_len = p_data->req_data.p_data->write_req.len;
|
||||
memcpy(recv_data.data, p_rec_data, recv_data.data_len);
|
||||
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = BTC_BLUFI_CB_ACT_RECV_DATA;
|
||||
|
||||
btc_transfer_context(&msg, &recv_data, sizeof(struct blufi_recv_evt_param), NULL);
|
||||
}
|
||||
break;
|
||||
case BTA_GATTS_CONF_EVT:
|
||||
/* Nothing */
|
||||
break;
|
||||
case BTA_GATTS_CREATE_EVT:
|
||||
uuid.uu.uuid16 = CHAR_BLUFI_UUID;
|
||||
blufi_cb_env.cur_srvc_id = p_data->create.service_id;
|
||||
blufi_cb_env.is_primery = p_data->create.is_primary;
|
||||
//start the blufi service after created
|
||||
BTA_GATTS_StartService(p_data->create.service_id, BTA_GATT_TRANSPORT_LE);
|
||||
//add the frist blufi characteristic --> write characteristic
|
||||
BTA_GATTS_AddCharacteristic(blufi_cb_env.cur_srvc_id, &uuid,
|
||||
(GATT_PERM_WRITE | GATT_PERM_READ),
|
||||
(GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_WRITE | GATT_CHAR_PROP_BIT_NOTIFY));
|
||||
break;
|
||||
case BTA_GATTS_ADD_CHAR_EVT:
|
||||
if (p_data->add_result.char_uuid.uu.uuid16 == CHAR_BLUFI_UUID) {
|
||||
//save the att handle to the env
|
||||
blufi_cb_env.blufi_inst.blufi_hdl = p_data->add_result.attr_id;
|
||||
|
||||
uuid.uu.uuid16 = GATT_UUID_CHAR_CLIENT_CONFIG;
|
||||
BTA_GATTS_AddCharDescriptor (blufi_cb_env.cur_srvc_id,
|
||||
(GATT_PERM_WRITE | GATT_PERM_WRITE),
|
||||
&uuid);
|
||||
}
|
||||
break;
|
||||
case BTA_GATTS_ADD_CHAR_DESCR_EVT: {
|
||||
/* call init finish */
|
||||
btc_msg_t msg;
|
||||
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_BLUFI;
|
||||
msg.act = BTC_BLUFI_CB_ACT_INIT_FINISH;
|
||||
btc_transfer_context(&msg, NULL, 0, NULL);
|
||||
break;
|
||||
}
|
||||
case BTA_GATTS_CONNECT_EVT:
|
||||
//set the connection flag to true
|
||||
LOG_ERROR("\ndevice is connected "BT_BD_ADDR_STR", server_if=%d,reason=0x%x,connect_id=%d\n",
|
||||
BT_BD_ADDR_HEX(p_data->conn.remote_bda), p_data->conn.server_if,
|
||||
p_data->conn.reason, p_data->conn.conn_id);
|
||||
|
||||
blufi_cb_env.conn_id = p_data->conn.conn_id;
|
||||
|
||||
/*return whether the remote device is currently connected*/
|
||||
int is_connected = BTA_DmGetConnectionState(p_data->conn.remote_bda);
|
||||
LOG_DEBUG("is_connected=%d\n", is_connected);
|
||||
BTA_DmBleBroadcast(0); //stop adv
|
||||
break;
|
||||
case BTA_GATTS_DISCONNECT_EVT:
|
||||
//set the connection flag to true
|
||||
blufi_cb_env.connected = false;
|
||||
break;
|
||||
case BTA_GATTS_OPEN_EVT:
|
||||
break;
|
||||
case BTA_GATTS_CLOSE_EVT:
|
||||
if (blufi_cb_env.connected && (blufi_cb_env.conn_id == p_data->conn.conn_id)) {
|
||||
//set the connection channal congested flag to true
|
||||
blufi_cb_env.congest = p_data->congest.congested;
|
||||
}
|
||||
break;
|
||||
case BTA_GATTS_LISTEN_EVT:
|
||||
break;
|
||||
case BTA_GATTS_CONGEST_EVT:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static tGATT_STATUS btc_blufi_profile_init(void)
|
||||
{
|
||||
tBT_UUID app_uuid = {LEN_UUID_16, {SVC_BLUFI_UUID}};
|
||||
|
||||
|
||||
if (blufi_cb_env.enabled) {
|
||||
LOG_ERROR("blufi svc already initaliezd");
|
||||
return GATT_ERROR;
|
||||
} else {
|
||||
memset(&blufi_cb_env, 0, sizeof(tBLUFI_CB_ENV));
|
||||
}
|
||||
|
||||
|
||||
/* register the blufi profile to the BTA_GATTS module*/
|
||||
BTA_GATTS_AppRegister(&app_uuid, blufi_profile_cb);
|
||||
|
||||
return GATT_SUCCESS;
|
||||
}
|
||||
|
||||
static void blufi_msg_notify(UINT8 *blufi_msg, UINT8 len)
|
||||
{
|
||||
BOOLEAN conn_status = blufi_cb_env.connected;
|
||||
UINT16 conn_id = blufi_cb_env.conn_id;
|
||||
UINT16 attr_id = blufi_cb_env.blufi_inst.blufi_hdl;
|
||||
//notify rsp==false; indicate rsp==true.
|
||||
BOOLEAN rsp = false;
|
||||
if (!conn_status && blufi_cb_env.congest) {
|
||||
LOG_ERROR("the conneciton for blufi profile has been loss");
|
||||
return;
|
||||
}
|
||||
|
||||
BTA_GATTS_HandleValueIndication (conn_id, attr_id, len,
|
||||
blufi_msg, rsp);
|
||||
}
|
||||
|
||||
static void btc_blufi_config_success(void)
|
||||
{
|
||||
LOG_DEBUG("config success\n");
|
||||
blufi_msg_notify(success_msg, strlen(success_msg));
|
||||
}
|
||||
|
||||
static void btc_blufi_config_failed(void)
|
||||
{
|
||||
LOG_DEBUG("config faield\n");
|
||||
blufi_msg_notify(failed_msg, strlen(failed_msg));
|
||||
}
|
||||
|
||||
void btc_blufi_cb_handler(btc_msg_t *msg)
|
||||
{
|
||||
esp_blufi_cb_param_t param;
|
||||
|
||||
switch (msg->act) {
|
||||
case BTC_BLUFI_CB_ACT_INIT_FINISH:
|
||||
param.init_finish.state = ESP_BLUFI_INIT_OK;
|
||||
BTC_BLUFI_CB_TO_APP(ESP_BLUFI_EVENT_INIT_FINISH, ¶m);
|
||||
break;
|
||||
case BTC_BLUFI_CB_ACT_DEINIT_FINISH:
|
||||
/* TODO: but now nothing */
|
||||
break;
|
||||
case BTC_BLUFI_CB_ACT_RECV_DATA:
|
||||
memcpy(¶m.recv_data, msg->arg, sizeof(struct blufi_recv_evt_param));
|
||||
|
||||
BTC_BLUFI_CB_TO_APP(ESP_BLUFI_EVENT_RECV_DATA, ¶m);
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("%s UNKNOWN %d\n", __func__, msg->act);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void btc_blufi_call_handler(btc_msg_t *msg)
|
||||
{
|
||||
btc_blufi_args_t *arg = (btc_blufi_args_t *)msg->arg;
|
||||
|
||||
switch (msg->act) {
|
||||
case BTC_BLUFI_ACT_INIT:
|
||||
btc_blufi_profile_init();
|
||||
break;
|
||||
case BTC_BLUFI_ACT_DEINIT:
|
||||
/* TODO: but now nothing */
|
||||
break;
|
||||
case BTC_BLUFI_ACT_SEND_CFG_STATE:
|
||||
if (arg->cfg_state.state == ESP_BLUFI_CONFIG_OK) {
|
||||
btc_blufi_config_success();
|
||||
} else {
|
||||
btc_blufi_config_failed();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG_ERROR("%s UNKNOWN %d\n", __func__, msg->act);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -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 __BLUFI_ADV_H__
|
||||
#define __BLUFI_ADV_H__
|
||||
|
||||
#include "bta_api.h"
|
||||
#include "btm_ble_api.h"
|
||||
#include "esp_bt_defs.h"
|
||||
|
||||
typedef enum {
|
||||
BLE_ADV_DATA_IDX = 0,
|
||||
BLE_SCAN_RSP_DATA_IDX = 1,
|
||||
ADV_SCAN_IDX_MAX,
|
||||
} ADV_SCAN_IDX_t;
|
||||
|
||||
typedef struct {
|
||||
char *adv_name; //set the device name to be sent on the advertising
|
||||
tBTA_BLE_ADV_DATA ble_adv_data;
|
||||
} tBLUFI_BLE_ADV_DATA;
|
||||
|
||||
extern void BlufiBleConfigadvData(tBLUFI_BLE_ADV_DATA *adv_data,
|
||||
tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback);
|
||||
|
||||
extern void BlufiBleSetScanRsp(tBLUFI_BLE_ADV_DATA *scan_rsp_data,
|
||||
tBTA_SET_ADV_DATA_CMPL_CBACK *p_scan_rsp_data_cback);
|
||||
|
||||
#endif /* __BLUFI_ADV_H__ */
|
||||
@@ -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 __BLUFI_INT_H__
|
||||
#define __BLUFI_INT_H__
|
||||
|
||||
//define the blufi serivce uuid
|
||||
#define SVC_BLUFI_UUID 0xFFFF
|
||||
//define the blufi Char uuid
|
||||
#define CHAR_BLUFI_UUID 0xFF01
|
||||
|
||||
#define BLUFI_HDL_NUM 4
|
||||
|
||||
#define BLUFI_VAL_MAX_LEN (128)
|
||||
|
||||
#define BLUFI_MAX_STRING_DATA 128
|
||||
|
||||
|
||||
typedef struct {
|
||||
UINT8 app_id;
|
||||
UINT16 blufi_hdl;
|
||||
} tBLUFI_INST;
|
||||
|
||||
|
||||
/* service engine control block */
|
||||
typedef struct {
|
||||
BOOLEAN enabled;
|
||||
BOOLEAN is_primery;
|
||||
UINT8 inst_id;
|
||||
tGATT_IF gatt_if;
|
||||
tBLUFI_INST blufi_inst;
|
||||
BOOLEAN in_use;
|
||||
BOOLEAN congest;
|
||||
UINT16 conn_id;
|
||||
BOOLEAN connected;
|
||||
BD_ADDR remote_bda;
|
||||
UINT32 trans_id;
|
||||
UINT8 cur_srvc_id;
|
||||
} tBLUFI_CB_ENV;
|
||||
|
||||
#endif /* __BLUFI_INT_H__ */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user