forked from espressif/esp-idf
Compare commits
504 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
055943e293 | ||
|
|
b34a0874b1 | ||
|
|
0d7f6a54e5 | ||
|
|
100379c4aa | ||
|
|
5d7d46a76d | ||
|
|
eaaad51f81 | ||
|
|
f21762eeef | ||
|
|
86e8983499 | ||
|
|
fa42f63226 | ||
|
|
483fc9be6f | ||
|
|
2ed18dcdd7 | ||
|
|
267ce80355 | ||
|
|
8b54542a88 | ||
|
|
030f17ae28 | ||
|
|
a8fe057219 | ||
|
|
1ffaf8aad9 | ||
|
|
9e7d9ef385 | ||
|
|
88eaa34075 | ||
|
|
b434b8f5d2 | ||
|
|
92dc6a6dde | ||
|
|
8e51f7e236 | ||
|
|
492c682dbe | ||
|
|
3886be23c8 | ||
|
|
ddbce78bff | ||
|
|
a230075447 | ||
|
|
4b5be79c0c | ||
|
|
b80b5dad32 | ||
|
|
ee39083d1b | ||
|
|
38b4d1d70c | ||
|
|
2e85c5b62e | ||
|
|
a820787414 | ||
|
|
cea6908238 | ||
|
|
d81c79d79f | ||
|
|
2f8508c7eb | ||
|
|
fd281c11cc | ||
|
|
6dd653392b | ||
|
|
dd623febf5 | ||
|
|
106c8813ed | ||
|
|
524308c98d | ||
|
|
553725df84 | ||
|
|
7d3733d255 | ||
|
|
038f51ffa6 | ||
|
|
4e78900fbf | ||
|
|
87215ca0c3 | ||
|
|
f6bfe13eb3 | ||
|
|
294a051538 | ||
|
|
4aa1058e8a | ||
|
|
a08c77ae96 | ||
|
|
df874cd070 | ||
|
|
36fff1d751 | ||
|
|
fe0d45d549 | ||
|
|
6f19193de6 | ||
|
|
8f4e7d2456 | ||
|
|
4156c6ddec | ||
|
|
cb20ba50b1 | ||
|
|
131979e517 | ||
|
|
9d6cace1fd | ||
|
|
a5b007f6bb | ||
|
|
0beb60e8fc | ||
|
|
9294e4d08d | ||
|
|
193b8e93a8 | ||
|
|
8da392aa1d | ||
|
|
c3cee5e3de | ||
|
|
0c13ae6b45 | ||
|
|
306a1173af | ||
|
|
592a4295be | ||
|
|
2549951498 | ||
|
|
b2384dc9ee | ||
|
|
f95826144e | ||
|
|
344cb99d34 | ||
|
|
464df4b788 | ||
|
|
8ff0d986b6 | ||
|
|
225bc0f80a | ||
|
|
96c8343e46 | ||
|
|
d9cdbcdc8b | ||
|
|
3ee11bcafc | ||
|
|
bcb543eb10 | ||
|
|
bb73659c9c | ||
|
|
58bc6be4c0 | ||
|
|
5059c7fac3 | ||
|
|
cf866f23f2 | ||
|
|
faec3211bd | ||
|
|
c7d0df5451 | ||
|
|
7097cb9c9d | ||
|
|
1fcef31195 | ||
|
|
acc882f4dd | ||
|
|
e4c1bcddc5 | ||
|
|
b2455219cc | ||
|
|
de6b7d6520 | ||
|
|
fa40e43c8d | ||
|
|
9f29dbf656 | ||
|
|
b2d61989f1 | ||
|
|
bb518afb59 | ||
|
|
37063ea9b6 | ||
|
|
f6837e6117 | ||
|
|
c4f39094d3 | ||
|
|
2da22620f8 | ||
|
|
f77d0a9cdb | ||
|
|
ddf4991024 | ||
|
|
f8597be435 | ||
|
|
6e5e430ef4 | ||
|
|
065d451e47 | ||
|
|
c8990eb39d | ||
|
|
c90f770599 | ||
|
|
48978c6f2b | ||
|
|
5bb5670d69 | ||
|
|
7197811861 | ||
|
|
892c2be168 | ||
|
|
5c6be8380e | ||
|
|
1d8e1c4ce4 | ||
|
|
1778573dad | ||
|
|
9778549759 | ||
|
|
e5e226a121 | ||
|
|
71845041e0 | ||
|
|
54dff92df5 | ||
|
|
a5bd08a6b6 | ||
|
|
befc74e0f0 | ||
|
|
12bf1017de | ||
|
|
006442cd9d | ||
|
|
25a134afdc | ||
|
|
70811110fc | ||
|
|
b87e440c69 | ||
|
|
f85294b058 | ||
|
|
413b6487fb | ||
|
|
f608afbe6b | ||
|
|
325fca94c0 | ||
|
|
3130b19cf8 | ||
|
|
5d2c23c8ab | ||
|
|
8480e79ae2 | ||
|
|
86052eec78 | ||
|
|
5ede49ca4a | ||
|
|
bbdb236ab7 | ||
|
|
0a0113bcce | ||
|
|
84a534a4a0 | ||
|
|
286202caa3 | ||
|
|
6b4dcd4f5c | ||
|
|
4f62227030 | ||
|
|
9ebaf36c28 | ||
|
|
1ece141c52 | ||
|
|
f49e2afe94 | ||
|
|
17b260d05c | ||
|
|
07fc1d181f | ||
|
|
beb29bc88a | ||
|
|
76c20ab9b3 | ||
|
|
241ba1a6bb | ||
|
|
1fac58deb7 | ||
|
|
78d32f2e8b | ||
|
|
f237b92bc4 | ||
|
|
ccc1263ca8 | ||
|
|
51a44c81de | ||
|
|
1b96cefaf8 | ||
|
|
ef82e8d0bc | ||
|
|
d6bdaed141 | ||
|
|
13018449fe | ||
|
|
b6687e56ed | ||
|
|
6494927766 | ||
|
|
6ce5c7668f | ||
|
|
c97a05c0d5 | ||
|
|
fed772641a | ||
|
|
39d8a89c80 | ||
|
|
62980ae995 | ||
|
|
029a155a71 | ||
|
|
4849d7ae90 | ||
|
|
10b4ddb467 | ||
|
|
288bc2bfca | ||
|
|
8e4ec90dc4 | ||
|
|
0e06b4d653 | ||
|
|
8fe4007dfa | ||
|
|
09f4015300 | ||
|
|
56918682f9 | ||
|
|
6b49a355f7 | ||
|
|
6628fddae6 | ||
|
|
ff99e0ea69 | ||
|
|
b305a96a74 | ||
|
|
fe4e68132f | ||
|
|
e870a0f0f1 | ||
|
|
12643e063c | ||
|
|
a7dc804476 | ||
|
|
7342811c37 | ||
|
|
8e0b0af09b | ||
|
|
e1e82c8949 | ||
|
|
d99d92e170 | ||
|
|
1ca67e98d6 | ||
|
|
f8f0c81077 | ||
|
|
727c2cfa00 | ||
|
|
1d4eeeb464 | ||
|
|
e9a764d9a5 | ||
|
|
b2e4af4ed0 | ||
|
|
66a0b64e54 | ||
|
|
9d48cdb6f3 | ||
|
|
258e9c98be | ||
|
|
35e491856e | ||
|
|
226c790766 | ||
|
|
c0d32f6e48 | ||
|
|
203f75223e | ||
|
|
742f8e7f8a | ||
|
|
7e16a79cf7 | ||
|
|
22dc4898d9 | ||
|
|
f78c96a3d7 | ||
|
|
b4727a8765 | ||
|
|
8bbd99ad9e | ||
|
|
5dcdef0639 | ||
|
|
d651ee3d28 | ||
|
|
34f1c208a8 | ||
|
|
83d7b4591c | ||
|
|
f5096892f9 | ||
|
|
56694fb4b6 | ||
|
|
929542d4fa | ||
|
|
be49c8d841 | ||
|
|
67aefe1011 | ||
|
|
46a3c36343 | ||
|
|
58e49d169c | ||
|
|
a241f95407 | ||
|
|
aaaa491c42 | ||
|
|
91aa35e831 | ||
|
|
113e829552 | ||
|
|
3802fddefb | ||
|
|
bb2eb9adeb | ||
|
|
78116afa01 | ||
|
|
b865e72aec | ||
|
|
f1b2457b6c | ||
|
|
46fa5654a7 | ||
|
|
bf28a1a27b | ||
|
|
b7beefba9e | ||
|
|
0784c52131 | ||
|
|
a7f826750b | ||
|
|
38086ae737 | ||
|
|
6173660ff0 | ||
|
|
79b450cfb4 | ||
|
|
c7fbc6dd85 | ||
|
|
3b5bba1812 | ||
|
|
b4feb67b5f | ||
|
|
578d7902af | ||
|
|
509884c5ac | ||
|
|
8a656f006e | ||
|
|
0f79c72704 | ||
|
|
6d6f71bbae | ||
|
|
332ccd0925 | ||
|
|
2ee1c6fd3e | ||
|
|
6a328992d7 | ||
|
|
b51f109dd7 | ||
|
|
85e8dea26a | ||
|
|
093c7b176d | ||
|
|
30e39631db | ||
|
|
a7ff611b10 | ||
|
|
2e64d2d56e | ||
|
|
3e6b402756 | ||
|
|
5568ca2855 | ||
|
|
30f2371917 | ||
|
|
ebaa944a9a | ||
|
|
d83598a64a | ||
|
|
00d1068869 | ||
|
|
49be9fb836 | ||
|
|
6f0c70daf6 | ||
|
|
219c85cf60 | ||
|
|
524696d59a | ||
|
|
9a229f4077 | ||
|
|
016c8d8b05 | ||
|
|
9914b839aa | ||
|
|
76e4ea7f68 | ||
|
|
3ec0f415a5 | ||
|
|
fa40b3d5d0 | ||
|
|
f742808333 | ||
|
|
51bd64c754 | ||
|
|
b85321be97 | ||
|
|
dcd63f73f6 | ||
|
|
b8f0c32a0a | ||
|
|
8f2e1471af | ||
|
|
a159e58ead | ||
|
|
fe767855df | ||
|
|
1e674fb4ed | ||
|
|
3660ccac4c | ||
|
|
4f9a4e8ed7 | ||
|
|
582bf18789 | ||
|
|
2e3f06ece8 | ||
|
|
c62a20f162 | ||
|
|
ed4d83af8e | ||
|
|
1444868917 | ||
|
|
05ba4f15d6 | ||
|
|
37b7153c0e | ||
|
|
1a53334843 | ||
|
|
fd29b0165f | ||
|
|
9c3262f80b | ||
|
|
900dbfd1f6 | ||
|
|
13a1f4ed78 | ||
|
|
8a69ffc36f | ||
|
|
a437e4dc5c | ||
|
|
741f97da4e | ||
|
|
eae2baa0f1 | ||
|
|
f49f5ff35a | ||
|
|
020b295f06 | ||
|
|
6e14de0fa8 | ||
|
|
95c7f45e84 | ||
|
|
651a08f710 | ||
|
|
18cb87b4ce | ||
|
|
1fedece94d | ||
|
|
137810915c | ||
|
|
bb766355b5 | ||
|
|
807ef53c38 | ||
|
|
e585121011 | ||
|
|
671be20cc5 | ||
|
|
022a9295b0 | ||
|
|
a34d788a5e | ||
|
|
2a47c5c7a4 | ||
|
|
cfc4f74b52 | ||
|
|
43a722f0de | ||
|
|
eff24857bc | ||
|
|
18118a6d5c | ||
|
|
64757c0228 | ||
|
|
bab80ad202 | ||
|
|
76f0dda3a4 | ||
|
|
ce9878ce71 | ||
|
|
403a24ab64 | ||
|
|
d2cf266762 | ||
|
|
cec39b750a | ||
|
|
0420f290a4 | ||
|
|
eb6dbeb15a | ||
|
|
5c9ab21d81 | ||
|
|
bab379faf8 | ||
|
|
fb7cd2a7a7 | ||
|
|
c208a6b451 | ||
|
|
78511c3cc3 | ||
|
|
cd6bbaa727 | ||
|
|
55b8f2ea8c | ||
|
|
ec2f1a6b9a | ||
|
|
26646b5b31 | ||
|
|
1ae9a2ae0b | ||
|
|
28eb488892 | ||
|
|
fcf1dba9cd | ||
|
|
94ed7b8298 | ||
|
|
24fab0b7a9 | ||
|
|
c4c1af114e | ||
|
|
b1ee25afde | ||
|
|
cccaa68467 | ||
|
|
6080767379 | ||
|
|
42b6c4953d | ||
|
|
746e831c19 | ||
|
|
36f9091e03 | ||
|
|
553ba51924 | ||
|
|
929d98538e | ||
|
|
b810b32675 | ||
|
|
00bf376bc3 | ||
|
|
fe19ea977b | ||
|
|
a953f73c64 | ||
|
|
bed50a93f0 | ||
|
|
a80bfc1dcf | ||
|
|
51d846417e | ||
|
|
ca54a5ce2a | ||
|
|
7b1777dd30 | ||
|
|
64b46ff1d9 | ||
|
|
c355d8a88e | ||
|
|
977af32d0f | ||
|
|
f0a6432717 | ||
|
|
c18e86a826 | ||
|
|
b5d53a0eff | ||
|
|
10afc3de77 | ||
|
|
545878d4e9 | ||
|
|
ec7909956d | ||
|
|
d9c3a08813 | ||
|
|
eb9a93f9b7 | ||
|
|
710019a47f | ||
|
|
2d27358f61 | ||
|
|
b80eba8d5a | ||
|
|
7832db7bb3 | ||
|
|
efa70bc8e3 | ||
|
|
31b7db5c38 | ||
|
|
8d02ccd2f7 | ||
|
|
62eb0f4c12 | ||
|
|
155f034b1e | ||
|
|
47dea73b03 | ||
|
|
28fdf96828 | ||
|
|
3969fe0dad | ||
|
|
c70c25afd0 | ||
|
|
d59d9eef4f | ||
|
|
22514e12d8 | ||
|
|
f48ffb37f2 | ||
|
|
0f041ee7bb | ||
|
|
c320a3ee4c | ||
|
|
1f35716ef4 | ||
|
|
358de85eb3 | ||
|
|
84277e5887 | ||
|
|
52a70e0489 | ||
|
|
6523d912f2 | ||
|
|
aa0d2078b7 | ||
|
|
348d6d5d3f | ||
|
|
46228db9a8 | ||
|
|
2cac11f162 | ||
|
|
64eeee4532 | ||
|
|
a9eb37e2c8 | ||
|
|
c7a297195f | ||
|
|
19e96add8a | ||
|
|
a0a0328e4f | ||
|
|
04aebc464c | ||
|
|
30e01847ad | ||
|
|
3f6033d8bd | ||
|
|
45e59a9f56 | ||
|
|
587e6ec93f | ||
|
|
6d00c7fc49 | ||
|
|
c418714ec6 | ||
|
|
19d8c050cd | ||
|
|
cb650382ca | ||
|
|
e5e592e5b6 | ||
|
|
28e20e90e3 | ||
|
|
1c4d9f2aca | ||
|
|
ded8b0102a | ||
|
|
401970495d | ||
|
|
5d46bb596d | ||
|
|
8de9149b11 | ||
|
|
e8b8946e6e | ||
|
|
2c1e3d1ef2 | ||
|
|
bf608b6709 | ||
|
|
24ebdbd3f4 | ||
|
|
fd00d3213b | ||
|
|
c921a5bc4b | ||
|
|
ade85cc850 | ||
|
|
5c8d25b795 | ||
|
|
ac051f0afc | ||
|
|
bb47146710 | ||
|
|
07cb228f64 | ||
|
|
3cfe1c89b5 | ||
|
|
4f805d558c | ||
|
|
f53716d851 | ||
|
|
f8fd922ca5 | ||
|
|
61d07ffbfc | ||
|
|
6b5649190f | ||
|
|
f44507de53 | ||
|
|
88c7a61a63 | ||
|
|
6af90457f7 | ||
|
|
3aafb2cfcf | ||
|
|
8ec0c82c3f | ||
|
|
a338c1b712 | ||
|
|
0b21be508e | ||
|
|
3b4d51bbfa | ||
|
|
60c556eb55 | ||
|
|
9933e37c8b | ||
|
|
67bdc8aaf4 | ||
|
|
44bd6f72bc | ||
|
|
2d67ce3109 | ||
|
|
e85cb6d148 | ||
|
|
7658b8ab62 | ||
|
|
7969a566e3 | ||
|
|
be05b1e654 | ||
|
|
ca51b60033 | ||
|
|
9b3ff1bed0 | ||
|
|
f859f9e25b | ||
|
|
f2ae151dab | ||
|
|
bae0d8a313 | ||
|
|
cfcc0edc33 | ||
|
|
54e6f0793a | ||
|
|
e98f4d2751 | ||
|
|
33cf0faac8 | ||
|
|
7385e71c84 | ||
|
|
7778ce83bd | ||
|
|
0f8070a6fd | ||
|
|
0fcb9056f8 | ||
|
|
5110d4b303 | ||
|
|
fc19954376 | ||
|
|
16d32c58e7 | ||
|
|
3d926da642 | ||
|
|
9bb719dd68 | ||
|
|
536cb0489e | ||
|
|
98c7cb5560 | ||
|
|
4baf333c79 | ||
|
|
79401934a1 | ||
|
|
ec1daf32e1 | ||
|
|
1cac0d2cf2 | ||
|
|
8d1594c339 | ||
|
|
a0f516de0b | ||
|
|
802d94aa35 | ||
|
|
3c3e375d8d | ||
|
|
d57ea422be | ||
|
|
3b3242cbae | ||
|
|
96c2b34eb9 | ||
|
|
6b3a8acdc3 | ||
|
|
a10abd695b | ||
|
|
0f28a51996 | ||
|
|
6681096e55 | ||
|
|
18b65dca26 | ||
|
|
a398116b1c | ||
|
|
331c7c7dc3 | ||
|
|
7bd9559e7e | ||
|
|
e84289077c | ||
|
|
c59c40741b | ||
|
|
f3c1903791 | ||
|
|
2885ec3831 | ||
|
|
a7db0e2291 | ||
|
|
cb98f5a814 | ||
|
|
8725bce5bc | ||
|
|
174b3b89e4 | ||
|
|
8d9d8e27ca | ||
|
|
93f4dc6b32 | ||
|
|
b021bbdc80 | ||
|
|
c9fe4fa13e | ||
|
|
96252c493a | ||
|
|
007a4fcc4e | ||
|
|
dbeb8ae02a | ||
|
|
9921c8b91f | ||
|
|
e16f65f4e6 | ||
|
|
fe0a5b41bf | ||
|
|
1f7c54ae85 | ||
|
|
049bd9fe0a | ||
|
|
167fb50a22 | ||
|
|
5f3b532c8d | ||
|
|
841a6dcd9a |
165
.flake8
165
.flake8
@@ -1,165 +0,0 @@
|
||||
[flake8]
|
||||
|
||||
select =
|
||||
# Full lists are given in order to suppress all errors from other plugins
|
||||
# Full list of pyflakes error codes:
|
||||
F401, # module imported but unused
|
||||
F402, # import module from line N shadowed by loop variable
|
||||
F403, # 'from module import *' used; unable to detect undefined names
|
||||
F404, # future import(s) name after other statements
|
||||
F405, # name may be undefined, or defined from star imports: module
|
||||
F406, # 'from module import *' only allowed at module level
|
||||
F407, # an undefined __future__ feature name was imported
|
||||
F601, # dictionary key name repeated with different values
|
||||
F602, # dictionary key variable name repeated with different values
|
||||
F621, # too many expressions in an assignment with star-unpacking
|
||||
F622, # two or more starred expressions in an assignment (a, *b, *c = d)
|
||||
F631, # assertion test is a tuple, which are always True
|
||||
F701, # a break statement outside of a while or for loop
|
||||
F702, # a continue statement outside of a while or for loop
|
||||
F703, # a continue statement in a finally block in a loop
|
||||
F704, # a yield or yield from statement outside of a function
|
||||
F705, # a return statement with arguments inside a generator
|
||||
F706, # a return statement outside of a function/method
|
||||
F707, # an except: block as not the last exception handler
|
||||
F721, F722, # doctest syntax error syntax error in forward type annotation
|
||||
F811, # redefinition of unused name from line N
|
||||
F812, # list comprehension redefines name from line N
|
||||
F821, # undefined name name
|
||||
F822, # undefined name name in __all__
|
||||
F823, # local variable name referenced before assignment
|
||||
F831, # duplicate argument name in function definition
|
||||
F841, # local variable name is assigned to but never used
|
||||
F901, # raise NotImplemented should be raise NotImplementedError
|
||||
|
||||
# Full list of pycodestyle violations:
|
||||
E101, # indentation contains mixed spaces and tabs
|
||||
E111, # indentation is not a multiple of four
|
||||
E112, # expected an indented block
|
||||
E113, # unexpected indentation
|
||||
E114, # indentation is not a multiple of four (comment)
|
||||
E115, # expected an indented block (comment)
|
||||
E116, # unexpected indentation (comment)
|
||||
E121, # continuation line under-indented for hanging indent
|
||||
E122, # continuation line missing indentation or outdented
|
||||
E123, # closing bracket does not match indentation of opening bracket's line
|
||||
E124, # closing bracket does not match visual indentation
|
||||
E125, # continuation line with same indent as next logical line
|
||||
E126, # continuation line over-indented for hanging indent
|
||||
E127, # continuation line over-indented for visual indent
|
||||
E128, # continuation line under-indented for visual indent
|
||||
E129, # visually indented line with same indent as next logical line
|
||||
E131, # continuation line unaligned for hanging indent
|
||||
E133, # closing bracket is missing indentation
|
||||
E201, # whitespace after '('
|
||||
E202, # whitespace before ')'
|
||||
E203, # whitespace before ':'
|
||||
E211, # whitespace before '('
|
||||
E221, # multiple spaces before operator
|
||||
E222, # multiple spaces after operator
|
||||
E223, # tab before operator
|
||||
E224, # tab after operator
|
||||
E225, # missing whitespace around operator
|
||||
E226, # missing whitespace around arithmetic operator
|
||||
E227, # missing whitespace around bitwise or shift operator
|
||||
E228, # missing whitespace around modulo operator
|
||||
E231, # missing whitespace after ',', ';', or ':'
|
||||
E241, # multiple spaces after ','
|
||||
E242, # tab after ','
|
||||
E251, # unexpected spaces around keyword / parameter equals
|
||||
E261, # at least two spaces before inline comment
|
||||
E262, # inline comment should start with '# '
|
||||
E265, # block comment should start with '# '
|
||||
E266, # too many leading '#' for block comment
|
||||
E271, # multiple spaces after keyword
|
||||
E272, # multiple spaces before keyword
|
||||
E273, # tab after keyword
|
||||
E274, # tab before keyword
|
||||
E275, # missing whitespace after keyword
|
||||
E301, # expected 1 blank line, found 0
|
||||
E302, # expected 2 blank lines, found 0
|
||||
E303, # too many blank lines
|
||||
E304, # blank lines found after function decorator
|
||||
E305, # expected 2 blank lines after end of function or class
|
||||
E306, # expected 1 blank line before a nested definition
|
||||
E401, # multiple imports on one line
|
||||
E402, # module level import not at top of file
|
||||
E501, # line too long (82 > 79 characters)
|
||||
E502, # the backslash is redundant between brackets
|
||||
E701, # multiple statements on one line (colon)
|
||||
E702, # multiple statements on one line (semicolon)
|
||||
E703, # statement ends with a semicolon
|
||||
E704, # multiple statements on one line (def)
|
||||
E711, # comparison to None should be 'if cond is None:'
|
||||
E712, # comparison to True should be 'if cond is True:' or 'if cond:'
|
||||
E713, # test for membership should be 'not in'
|
||||
E714, # test for object identity should be 'is not'
|
||||
E721, # do not compare types, use 'isinstance()'
|
||||
E722, # do not use bare except, specify exception instead
|
||||
E731, # do not assign a lambda expression, use a def
|
||||
E741, # do not use variables named 'l', 'O', or 'I'
|
||||
E742, # do not define classes named 'l', 'O', or 'I'
|
||||
E743, # do not define functions named 'l', 'O', or 'I'
|
||||
E901, # SyntaxError or IndentationError
|
||||
E902, # IOError
|
||||
W191, # indentation contains tabs
|
||||
W291, # trailing whitespace
|
||||
W292, # no newline at end of file
|
||||
W293, # blank line contains whitespace
|
||||
W391, # blank line at end of file
|
||||
W503, # line break before binary operator
|
||||
W504, # line break after binary operator
|
||||
W505, # doc line too long (82 > 79 characters)
|
||||
W601, # .has_key() is deprecated, use 'in'
|
||||
W602, # deprecated form of raising exception
|
||||
W603, # '<>' is deprecated, use '!='
|
||||
W604, # backticks are deprecated, use 'repr()'
|
||||
W605, # invalid escape sequence 'x'
|
||||
W606, # 'async' and 'await' are reserved keywords starting with Python 3.7
|
||||
|
||||
# Full list of flake8 violations
|
||||
E999, # failed to compile a file into an Abstract Syntax Tree for the plugins that require it
|
||||
|
||||
# Full list of mccabe violations
|
||||
C901 # complexity value provided by the user
|
||||
|
||||
ignore =
|
||||
E221, # multiple spaces before operator
|
||||
E231, # missing whitespace after ',', ';', or ':'
|
||||
E241, # multiple spaces after ','
|
||||
W503, # line break before binary operator
|
||||
W504 # line break after binary operator
|
||||
|
||||
max-line-length = 160
|
||||
|
||||
show_source = True
|
||||
|
||||
statistics = True
|
||||
|
||||
exclude =
|
||||
.git,
|
||||
__pycache__,
|
||||
# submodules
|
||||
components/esptool_py/esptool,
|
||||
components/micro-ecc/micro-ecc,
|
||||
components/nghttp/nghttp2,
|
||||
components/libsodium/libsodium,
|
||||
components/json/cJSON,
|
||||
components/mbedtls/mbedtls,
|
||||
components/expat/expat,
|
||||
components/unity/unity,
|
||||
examples/build_system/cmake/import_lib/main/lib/tinyxml2
|
||||
# other third-party libraries
|
||||
tools/kconfig_new/kconfiglib.py,
|
||||
# autogenerated scripts
|
||||
components/protocomm/python/constants_pb2.py,
|
||||
components/protocomm/python/sec0_pb2.py,
|
||||
components/protocomm/python/sec1_pb2.py,
|
||||
components/protocomm/python/session_pb2.py,
|
||||
components/wifi_provisioning/python/wifi_scan_pb2.py,
|
||||
components/wifi_provisioning/python/wifi_config_pb2.py,
|
||||
components/wifi_provisioning/python/wifi_constants_pb2.py,
|
||||
examples/provisioning/custom_config/components/custom_provisioning/python/custom_config_pb2.py,
|
||||
# temporary list (should be empty)
|
||||
tools/esp_app_trace/pylibelf,
|
||||
tools/mass_mfg/mfg_gen.py,
|
||||
17
.github/main.workflow
vendored
17
.github/main.workflow
vendored
@@ -1,17 +0,0 @@
|
||||
workflow "Sync issues to JIRA" {
|
||||
on = "issues"
|
||||
resolves = ["Sync to JIRA"]
|
||||
}
|
||||
|
||||
workflow "Sync issue comments to JIRA" {
|
||||
on = "issue_comment"
|
||||
resolves = ["Sync to JIRA"]
|
||||
}
|
||||
|
||||
action "Sync to JIRA" {
|
||||
uses = "espressif/github-actions/sync_issues_to_jira@master"
|
||||
secrets = ["GITHUB_TOKEN", "JIRA_URL", "JIRA_USER", "JIRA_PASS"]
|
||||
env = {
|
||||
JIRA_PROJECT = "IDFGH"
|
||||
}
|
||||
}
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -68,9 +68,3 @@ test_multi_heap_host
|
||||
|
||||
# VS Code Settings
|
||||
.vscode/
|
||||
|
||||
# Results for the checking of the Python coding style
|
||||
flake8_output.txt
|
||||
|
||||
# ESP-IDF library
|
||||
build
|
||||
|
||||
1150
.gitlab-ci.yml
1150
.gitlab-ci.yml
File diff suppressed because it is too large
Load Diff
12
.gitmodules
vendored
12
.gitmodules
vendored
@@ -61,15 +61,3 @@
|
||||
[submodule "components/protobuf-c/protobuf-c"]
|
||||
path = components/protobuf-c/protobuf-c
|
||||
url = https://github.com/protobuf-c/protobuf-c
|
||||
|
||||
[submodule "components/unity/unity"]
|
||||
path = components/unity/unity
|
||||
url = https://github.com/ThrowTheSwitch/Unity
|
||||
|
||||
[submodule "examples/build_system/cmake/import_lib/main/lib/tinyxml2"]
|
||||
path = examples/build_system/cmake/import_lib/main/lib/tinyxml2
|
||||
url = https://github.com/leethomason/tinyxml2
|
||||
|
||||
[submodule "components/nimble/nimble"]
|
||||
path = components/nimble/nimble
|
||||
url = https://github.com/espressif/esp-nimble.git
|
||||
|
||||
@@ -7,6 +7,7 @@ version: 2
|
||||
|
||||
# Optionally build your docs in additional formats such as PDF and ePub
|
||||
formats:
|
||||
- htmlzip
|
||||
- pdf
|
||||
|
||||
# Optionally set the version of Python and requirements required to build your docs
|
||||
@@ -15,7 +16,7 @@ python:
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
|
||||
# We need to list all the submodules included in documentation build by Doxygen
|
||||
# We need to list all the submodules included in documenation build by Doxygen
|
||||
submodules:
|
||||
include:
|
||||
- components/mqtt/esp-mqtt
|
||||
@@ -1,7 +0,0 @@
|
||||
language: python
|
||||
sudo: false
|
||||
python:
|
||||
- "3.4"
|
||||
script:
|
||||
- pip install flake8
|
||||
- travis_wait 20 python -m flake8 --config=.flake8 .
|
||||
@@ -1,45 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(esp-idf C CXX ASM)
|
||||
|
||||
#
|
||||
# Add each component to the build as a library
|
||||
#
|
||||
foreach(COMPONENT_PATH ${BUILD_COMPONENT_PATHS})
|
||||
get_filename_component(COMPONENT_NAME ${COMPONENT_PATH} NAME)
|
||||
|
||||
list(FIND BUILD_TEST_COMPONENT_PATHS ${COMPONENT_PATH} idx)
|
||||
|
||||
if(NOT idx EQUAL -1)
|
||||
list(GET BUILD_TEST_COMPONENTS ${idx} test_component)
|
||||
set(COMPONENT_NAME ${test_component})
|
||||
endif()
|
||||
|
||||
component_get_target(COMPONENT_TARGET ${COMPONENT_NAME})
|
||||
|
||||
add_subdirectory(${COMPONENT_PATH} ${COMPONENT_NAME})
|
||||
endforeach()
|
||||
unset(COMPONENT_NAME)
|
||||
unset(COMPONENT_PATH)
|
||||
|
||||
# each component should see the include directories of its requirements
|
||||
#
|
||||
# (we can't do this until all components are registered and targets exist in cmake, as we have
|
||||
# a circular requirements graph...)
|
||||
foreach(component ${BUILD_COMPONENTS})
|
||||
component_get_target(component_target ${component})
|
||||
if(TARGET ${component_target})
|
||||
get_component_requirements(${component} deps priv_deps)
|
||||
|
||||
list(APPEND priv_deps ${IDF_COMPONENT_REQUIRES_COMMON})
|
||||
|
||||
foreach(dep ${deps})
|
||||
component_get_target(dep_target ${dep})
|
||||
add_component_dependencies(${component_target} ${dep_target} PUBLIC)
|
||||
endforeach()
|
||||
|
||||
foreach(dep ${priv_deps})
|
||||
component_get_target(dep_target ${dep})
|
||||
add_component_dependencies(${component_target} ${dep_target} PRIVATE)
|
||||
endforeach()
|
||||
endif()
|
||||
endforeach()
|
||||
@@ -53,7 +53,6 @@ Related Documents
|
||||
|
||||
style-guide
|
||||
documenting-code
|
||||
add-ons-reference
|
||||
creating-examples
|
||||
../api-reference/template
|
||||
contributor-agreement
|
||||
|
||||
369
Kconfig
369
Kconfig
@@ -4,208 +4,187 @@
|
||||
#
|
||||
mainmenu "Espressif IoT Development Framework Configuration"
|
||||
|
||||
config IDF_CMAKE
|
||||
bool
|
||||
option env="IDF_CMAKE"
|
||||
config IDF_CMAKE
|
||||
bool
|
||||
option env="IDF_CMAKE"
|
||||
|
||||
menu "SDK tool configuration"
|
||||
config TOOLPREFIX
|
||||
string "Compiler toolchain path/prefix"
|
||||
default "xtensa-esp32-elf-"
|
||||
help
|
||||
The prefix/path that is used to call the toolchain. The default setting assumes
|
||||
a crosstool-ng gcc setup that is in your PATH.
|
||||
|
||||
config PYTHON
|
||||
string "Python 2 interpreter"
|
||||
depends on !IDF_CMAKE
|
||||
default "python"
|
||||
help
|
||||
The executable name/path that is used to run python. On some systems Python 2.x
|
||||
may need to be invoked as python2.
|
||||
|
||||
(Note: This option is used with the GNU Make build system only, not idf.py
|
||||
or CMake-based builds.)
|
||||
|
||||
config MAKE_WARN_UNDEFINED_VARIABLES
|
||||
bool "'make' warns on undefined variables"
|
||||
default "y"
|
||||
help
|
||||
Adds --warn-undefined-variables to MAKEFLAGS. This causes make to
|
||||
print a warning any time an undefined variable is referenced.
|
||||
|
||||
This option helps find places where a variable reference is misspelled
|
||||
or otherwise missing, but it can be unwanted if you have Makefiles which
|
||||
depend on undefined variables expanding to an empty string.
|
||||
|
||||
endmenu # SDK tool configuration
|
||||
|
||||
source "$COMPONENT_KCONFIGS_PROJBUILD"
|
||||
|
||||
menu "Compiler options"
|
||||
|
||||
choice OPTIMIZATION_COMPILER
|
||||
prompt "Optimization Level"
|
||||
default OPTIMIZATION_LEVEL_DEBUG
|
||||
help
|
||||
This option sets compiler optimization level (gcc -O argument).
|
||||
|
||||
- for "Release" setting, -Os flag is added to CFLAGS.
|
||||
- for "Debug" setting, -Og flag is added to CFLAGS.
|
||||
|
||||
"Release" with -Os produces smaller & faster compiled code but it
|
||||
may be harder to correlated code addresses to source files when debugging.
|
||||
|
||||
To add custom optimization settings, set CFLAGS and/or CPPFLAGS
|
||||
in project makefile, before including $(IDF_PATH)/make/project.mk. Note that
|
||||
custom optimization levels may be unsupported.
|
||||
|
||||
config OPTIMIZATION_LEVEL_DEBUG
|
||||
bool "Debug (-Og)"
|
||||
config OPTIMIZATION_LEVEL_RELEASE
|
||||
bool "Release (-Os)"
|
||||
endchoice
|
||||
|
||||
choice OPTIMIZATION_ASSERTION_LEVEL
|
||||
prompt "Assertion level"
|
||||
default OPTIMIZATION_ASSERTIONS_ENABLED
|
||||
help
|
||||
Assertions can be:
|
||||
|
||||
- Enabled. Failure will print verbose assertion details. This is the default.
|
||||
|
||||
- Set to "silent" to save code size (failed assertions will abort() but user
|
||||
needs to use the aborting address to find the line number with the failed assertion.)
|
||||
|
||||
- Disabled entirely (not recommended for most configurations.) -DNDEBUG is added
|
||||
to CPPFLAGS in this case.
|
||||
|
||||
config OPTIMIZATION_ASSERTIONS_ENABLED
|
||||
prompt "Enabled"
|
||||
bool
|
||||
help
|
||||
Enable assertions. Assertion content and line number will be printed on failure.
|
||||
|
||||
config OPTIMIZATION_ASSERTIONS_SILENT
|
||||
prompt "Silent (saves code size)"
|
||||
bool
|
||||
help
|
||||
Enable silent assertions. Failed assertions will abort(), user needs to
|
||||
use the aborting address to find the line number with the failed assertion.
|
||||
|
||||
config OPTIMIZATION_ASSERTIONS_DISABLED
|
||||
prompt "Disabled (sets -DNDEBUG)"
|
||||
bool
|
||||
help
|
||||
If assertions are disabled, -DNDEBUG is added to CPPFLAGS.
|
||||
|
||||
endchoice # assertions
|
||||
|
||||
menuconfig CXX_EXCEPTIONS
|
||||
bool "Enable C++ exceptions"
|
||||
default n
|
||||
help
|
||||
Enabling this option compiles all IDF C++ files with exception support enabled.
|
||||
|
||||
Disabling this option disables C++ exception support in all compiled files, and any libstdc++ code which throws
|
||||
an exception will abort instead.
|
||||
|
||||
Enabling this option currently adds an additional ~500 bytes of heap overhead
|
||||
when an exception is thrown in user code for the first time.
|
||||
|
||||
config CXX_EXCEPTIONS_EMG_POOL_SIZE
|
||||
int "Emergency Pool Size"
|
||||
default 0
|
||||
depends on CXX_EXCEPTIONS
|
||||
help
|
||||
Size (in bytes) of the emergency memory pool for C++ exceptions. This pool will be used to allocate
|
||||
memory for thrown exceptions when there is not enough memory on the heap.
|
||||
|
||||
choice STACK_CHECK_MODE
|
||||
prompt "Stack smashing protection mode"
|
||||
default STACK_CHECK_NONE
|
||||
help
|
||||
Stack smashing protection mode. Emit extra code to check for buffer overflows, such as stack
|
||||
smashing attacks. This is done by adding a guard variable to functions with vulnerable objects.
|
||||
The guards are initialized when a function is entered and then checked when the function exits.
|
||||
If a guard check fails, program is halted. Protection has the following modes:
|
||||
|
||||
- In NORMAL mode (GCC flag: -fstack-protector) only functions that call alloca,
|
||||
and functions with buffers larger than 8 bytes are protected.
|
||||
|
||||
- STRONG mode (GCC flag: -fstack-protector-strong) is like NORMAL, but includes
|
||||
additional functions to be protected -- those that have local array definitions,
|
||||
or have references to local frame addresses.
|
||||
|
||||
- In OVERALL mode (GCC flag: -fstack-protector-all) all functions are protected.
|
||||
|
||||
Modes have the following impact on code performance and coverage:
|
||||
|
||||
- performance: NORMAL > STRONG > OVERALL
|
||||
|
||||
- coverage: NORMAL < STRONG < OVERALL
|
||||
|
||||
|
||||
config IDF_TARGET_ENV
|
||||
# A proxy to get environment variable $IDF_TARGET
|
||||
string
|
||||
option env="IDF_TARGET"
|
||||
config STACK_CHECK_NONE
|
||||
bool "None"
|
||||
config STACK_CHECK_NORM
|
||||
bool "Normal"
|
||||
config STACK_CHECK_STRONG
|
||||
bool "Strong"
|
||||
config STACK_CHECK_ALL
|
||||
bool "Overall"
|
||||
endchoice
|
||||
|
||||
config IDF_TARGET
|
||||
# This option records the IDF target when sdkconfig is generated the first time.
|
||||
# It is not updated if environment variable $IDF_TARGET changes later, and
|
||||
# the build system is responsible for detecting the mismatch between
|
||||
# CONFIG_IDF_TARGET and $IDF_TARGET.
|
||||
string
|
||||
default "IDF_TARGET_NOT_SET" if IDF_TARGET_ENV=""
|
||||
default IDF_TARGET_ENV
|
||||
config STACK_CHECK
|
||||
bool
|
||||
default !STACK_CHECK_NONE
|
||||
help
|
||||
Stack smashing protection.
|
||||
|
||||
config IDF_FIRMWARE_CHIP_ID
|
||||
hex
|
||||
default 0x0000 if IDF_TARGET="esp32"
|
||||
default 0xFFFF
|
||||
config WARN_WRITE_STRINGS
|
||||
bool "Enable -Wwrite-strings warning flag"
|
||||
default "n"
|
||||
help
|
||||
Adds -Wwrite-strings flag for the C/C++ compilers.
|
||||
|
||||
menu "SDK tool configuration"
|
||||
config TOOLPREFIX
|
||||
string "Compiler toolchain path/prefix"
|
||||
default "xtensa-esp32-elf-"
|
||||
help
|
||||
The prefix/path that is used to call the toolchain. The default setting assumes
|
||||
a crosstool-ng gcc setup that is in your PATH.
|
||||
For C, this gives string constants the type ``const char[]`` so that
|
||||
copying the address of one into a non-const ``char *`` pointer
|
||||
produces a warning. This warning helps to find at compile time code
|
||||
that tries to write into a string constant.
|
||||
|
||||
config PYTHON
|
||||
string "Python 2 interpreter"
|
||||
depends on !IDF_CMAKE
|
||||
default "python"
|
||||
help
|
||||
The executable name/path that is used to run python. On some systems Python 2.x
|
||||
may need to be invoked as python2.
|
||||
For C++, this warns about the deprecated conversion from string
|
||||
literals to ``char *``.
|
||||
|
||||
(Note: This option is used with the GNU Make build system only, not idf.py
|
||||
or CMake-based builds.)
|
||||
|
||||
config MAKE_WARN_UNDEFINED_VARIABLES
|
||||
bool "'make' warns on undefined variables"
|
||||
default "y"
|
||||
help
|
||||
Adds --warn-undefined-variables to MAKEFLAGS. This causes make to
|
||||
print a warning any time an undefined variable is referenced.
|
||||
|
||||
This option helps find places where a variable reference is misspelled
|
||||
or otherwise missing, but it can be unwanted if you have Makefiles which
|
||||
depend on undefined variables expanding to an empty string.
|
||||
|
||||
endmenu # SDK tool configuration
|
||||
|
||||
source "$COMPONENT_KCONFIGS_PROJBUILD"
|
||||
|
||||
menu "Compiler options"
|
||||
|
||||
choice OPTIMIZATION_COMPILER
|
||||
prompt "Optimization Level"
|
||||
default OPTIMIZATION_LEVEL_DEBUG
|
||||
help
|
||||
This option sets compiler optimization level (gcc -O argument).
|
||||
|
||||
- for "Release" setting, -Os flag is added to CFLAGS.
|
||||
- for "Debug" setting, -Og flag is added to CFLAGS.
|
||||
|
||||
"Release" with -Os produces smaller & faster compiled code but it
|
||||
may be harder to correlated code addresses to source files when debugging.
|
||||
|
||||
To add custom optimization settings, set CFLAGS and/or CPPFLAGS
|
||||
in project makefile, before including $(IDF_PATH)/make/project.mk. Note that
|
||||
custom optimization levels may be unsupported.
|
||||
|
||||
config OPTIMIZATION_LEVEL_DEBUG
|
||||
bool "Debug (-Og)"
|
||||
config OPTIMIZATION_LEVEL_RELEASE
|
||||
bool "Release (-Os)"
|
||||
endchoice
|
||||
|
||||
choice OPTIMIZATION_ASSERTION_LEVEL
|
||||
prompt "Assertion level"
|
||||
default OPTIMIZATION_ASSERTIONS_ENABLED
|
||||
help
|
||||
Assertions can be:
|
||||
|
||||
- Enabled. Failure will print verbose assertion details. This is the default.
|
||||
|
||||
- Set to "silent" to save code size (failed assertions will abort() but user
|
||||
needs to use the aborting address to find the line number with the failed assertion.)
|
||||
|
||||
- Disabled entirely (not recommended for most configurations.) -DNDEBUG is added
|
||||
to CPPFLAGS in this case.
|
||||
|
||||
config OPTIMIZATION_ASSERTIONS_ENABLED
|
||||
prompt "Enabled"
|
||||
bool
|
||||
help
|
||||
Enable assertions. Assertion content and line number will be printed on failure.
|
||||
|
||||
config OPTIMIZATION_ASSERTIONS_SILENT
|
||||
prompt "Silent (saves code size)"
|
||||
bool
|
||||
help
|
||||
Enable silent assertions. Failed assertions will abort(), user needs to
|
||||
use the aborting address to find the line number with the failed assertion.
|
||||
|
||||
config OPTIMIZATION_ASSERTIONS_DISABLED
|
||||
prompt "Disabled (sets -DNDEBUG)"
|
||||
bool
|
||||
help
|
||||
If assertions are disabled, -DNDEBUG is added to CPPFLAGS.
|
||||
|
||||
endchoice # assertions
|
||||
|
||||
menuconfig CXX_EXCEPTIONS
|
||||
bool "Enable C++ exceptions"
|
||||
default n
|
||||
help
|
||||
Enabling this option compiles all IDF C++ files with exception support enabled.
|
||||
|
||||
Disabling this option disables C++ exception support in all compiled files, and any libstdc++ code
|
||||
which throws an exception will abort instead.
|
||||
|
||||
Enabling this option currently adds an additional ~500 bytes of heap overhead
|
||||
when an exception is thrown in user code for the first time.
|
||||
|
||||
config CXX_EXCEPTIONS_EMG_POOL_SIZE
|
||||
int "Emergency Pool Size"
|
||||
default 0
|
||||
depends on CXX_EXCEPTIONS
|
||||
help
|
||||
Size (in bytes) of the emergency memory pool for C++ exceptions. This pool will be used to allocate
|
||||
memory for thrown exceptions when there is not enough memory on the heap.
|
||||
|
||||
choice STACK_CHECK_MODE
|
||||
prompt "Stack smashing protection mode"
|
||||
default STACK_CHECK_NONE
|
||||
help
|
||||
Stack smashing protection mode. Emit extra code to check for buffer overflows, such as stack
|
||||
smashing attacks. This is done by adding a guard variable to functions with vulnerable objects.
|
||||
The guards are initialized when a function is entered and then checked when the function exits.
|
||||
If a guard check fails, program is halted. Protection has the following modes:
|
||||
|
||||
- In NORMAL mode (GCC flag: -fstack-protector) only functions that call alloca, and functions with
|
||||
buffers larger than 8 bytes are protected.
|
||||
|
||||
- STRONG mode (GCC flag: -fstack-protector-strong) is like NORMAL, but includes additional functions
|
||||
to be protected -- those that have local array definitions, or have references to local frame
|
||||
addresses.
|
||||
|
||||
- In OVERALL mode (GCC flag: -fstack-protector-all) all functions are protected.
|
||||
|
||||
Modes have the following impact on code performance and coverage:
|
||||
|
||||
- performance: NORMAL > STRONG > OVERALL
|
||||
|
||||
- coverage: NORMAL < STRONG < OVERALL
|
||||
config DISABLE_GCC8_WARNINGS
|
||||
bool "Disable new warnings introduced in GCC 6 - 8"
|
||||
default "n"
|
||||
help
|
||||
Enable this option if using GCC 6 or newer, and wanting to disable warnings which don't appear with GCC 5.
|
||||
|
||||
|
||||
config STACK_CHECK_NONE
|
||||
bool "None"
|
||||
config STACK_CHECK_NORM
|
||||
bool "Normal"
|
||||
config STACK_CHECK_STRONG
|
||||
bool "Strong"
|
||||
config STACK_CHECK_ALL
|
||||
bool "Overall"
|
||||
endchoice
|
||||
endmenu # Compiler Options
|
||||
|
||||
config STACK_CHECK
|
||||
bool
|
||||
default !STACK_CHECK_NONE
|
||||
help
|
||||
Stack smashing protection.
|
||||
|
||||
config WARN_WRITE_STRINGS
|
||||
bool "Enable -Wwrite-strings warning flag"
|
||||
default "n"
|
||||
help
|
||||
Adds -Wwrite-strings flag for the C/C++ compilers.
|
||||
|
||||
For C, this gives string constants the type ``const char[]`` so that
|
||||
copying the address of one into a non-const ``char *`` pointer
|
||||
produces a warning. This warning helps to find at compile time code
|
||||
that tries to write into a string constant.
|
||||
|
||||
For C++, this warns about the deprecated conversion from string
|
||||
literals to ``char *``.
|
||||
|
||||
config DISABLE_GCC8_WARNINGS
|
||||
bool "Disable new warnings introduced in GCC 6 - 8"
|
||||
default "n"
|
||||
help
|
||||
Enable this option if using GCC 6 or newer, and wanting to disable warnings which don't appear with
|
||||
GCC 5.
|
||||
|
||||
|
||||
endmenu # Compiler Options
|
||||
|
||||
menu "Component config"
|
||||
source "$COMPONENT_KCONFIGS"
|
||||
endmenu
|
||||
menu "Component config"
|
||||
source "$COMPONENT_KCONFIGS"
|
||||
endmenu
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
The latest support policy for ESP-IDF can be found at [https://github.com/espressif/esp-idf/blob/master/SUPPORT_POLICY.md](https://github.com/espressif/esp-idf/blob/master/SUPPORT_POLICY.md)
|
||||
|
||||
Support Period Policy
|
||||
=====================
|
||||
|
||||
Each ESP-IDF major and minor release (V4.0, V4.1, etc) is supported for
|
||||
18 months after the initial stable release date.
|
||||
|
||||
Supported means that the ESP-IDF team will continue to apply bug fixes,
|
||||
security fixes, etc to the release branch on GitHub, and periodically
|
||||
make new bugfix releases as needed.
|
||||
|
||||
Users are encouraged to upgrade to a newer ESP-IDF release before the
|
||||
support period finishes and the release becomes End of Life (EOL). It is
|
||||
our policy to not continue fixing bugs in End of Life releases.
|
||||
|
||||
Pre-release versions (betas, previews, `-rc` and `-dev` versions, etc)
|
||||
are not covered by any support period. Sometimes a particular feature is
|
||||
marked as \"Preview\" in a release, which means it is also not covered
|
||||
by the support period.
|
||||
|
||||
The ESP-IDF Programming Guide has information about the
|
||||
[different versions of ESP-IDF](https://docs.espressif.com/projects/esp-idf/en/latest/versions.html)
|
||||
(major, minor, bugfix, etc).
|
||||
|
||||
Long Term Support releases
|
||||
--------------------------
|
||||
|
||||
Some releases (starting with ESP-IDF V3.3) are designated Long Term
|
||||
Support (LTS). LTS releases are supported for 30 months (2.5 years)
|
||||
after the initial stable release date.
|
||||
|
||||
A new LTS release will be made at least every 18 months. This means
|
||||
there will always be a period of at least 12 months to upgrade from the
|
||||
previous LTS release to the following LTS release.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
ESP-IDF V3.3 was released in September 2019 and is a Long Term Support
|
||||
(LTS) release, meaning it will be supported for 30 months until February
|
||||
2022.
|
||||
|
||||
- The first V3.3 release was `v3.3` in September 2019.
|
||||
- The ESP-IDF team continues to backport bug fixes, security fixes,
|
||||
etc to the release branch `release/v3.3`.
|
||||
- Periodically stable bugfix releases are created from the release
|
||||
branch. For example `v3.3.1`, `v3.3.2`, etc. Users are encouraged to
|
||||
always update to the latest bugfix release.
|
||||
- V3.3 bugfix releases continue until February 2022, when all V3.3.x
|
||||
releases become End of Life.
|
||||
|
||||
Existing Releases
|
||||
-----------------
|
||||
|
||||
ESP-IDF release V3.3 and all newer releases will follow this support
|
||||
period policy. The support period for each release will be announced
|
||||
when the release is made.
|
||||
|
||||
For releases made before the support period policy was announced,
|
||||
the following support periods apply:
|
||||
|
||||
- ESP-IDF V3.1.x and V3.2.x will both be supported until October 2020.
|
||||
- ESP-IDF V3.0.9 (planned for October 2019) will be the last V3.0
|
||||
bugfix release. ESP-IDF V3.0.x is End of Life from October 2019.
|
||||
- ESP-IDF versions before V3.0 are already End of Life.
|
||||
@@ -9,7 +9,6 @@
|
||||
if [ -z ${IDF_PATH} ]; then
|
||||
echo "IDF_PATH must be set before including this script."
|
||||
else
|
||||
IDF_ADD_PATHS_EXTRAS=
|
||||
IDF_ADD_PATHS_EXTRAS="${IDF_ADD_PATHS_EXTRAS}:${IDF_PATH}/components/esptool_py/esptool"
|
||||
IDF_ADD_PATHS_EXTRAS="${IDF_ADD_PATHS_EXTRAS}:${IDF_PATH}/components/espcoredump"
|
||||
IDF_ADD_PATHS_EXTRAS="${IDF_ADD_PATHS_EXTRAS}:${IDF_PATH}/components/partition_table/"
|
||||
|
||||
@@ -18,7 +18,6 @@ endif()
|
||||
|
||||
set(COMPONENT_REQUIRES)
|
||||
set(COMPONENT_PRIV_REQUIRES xtensa-debug-module)
|
||||
set(COMPONENT_ADD_LDFRAGMENTS linker.lf)
|
||||
|
||||
register_component()
|
||||
|
||||
@@ -26,4 +25,4 @@ register_component()
|
||||
# for gcov
|
||||
component_compile_options("-fno-profile-arcs" "-fno-test-coverage")
|
||||
|
||||
target_link_libraries(${COMPONENT_TARGET} gcov)
|
||||
target_link_libraries(app_trace gcov)
|
||||
|
||||
@@ -1,210 +1,202 @@
|
||||
menu "Application Level Tracing"
|
||||
|
||||
choice ESP32_APPTRACE_DESTINATION
|
||||
prompt "Data Destination"
|
||||
default ESP32_APPTRACE_DEST_NONE
|
||||
help
|
||||
Select destination for application trace: trace memory or none (to disable).
|
||||
choice ESP32_APPTRACE_DESTINATION
|
||||
prompt "Data Destination"
|
||||
default ESP32_APPTRACE_DEST_NONE
|
||||
help
|
||||
Select destination for application trace: trace memory or none (to disable).
|
||||
|
||||
config ESP32_APPTRACE_DEST_TRAX
|
||||
bool "Trace memory"
|
||||
select ESP32_APPTRACE_ENABLE
|
||||
config ESP32_APPTRACE_DEST_NONE
|
||||
bool "None"
|
||||
endchoice
|
||||
config ESP32_APPTRACE_DEST_TRAX
|
||||
bool "Trace memory"
|
||||
select ESP32_APPTRACE_ENABLE
|
||||
config ESP32_APPTRACE_DEST_NONE
|
||||
bool "None"
|
||||
endchoice
|
||||
|
||||
config ESP32_APPTRACE_ENABLE
|
||||
bool
|
||||
depends on !ESP32_TRAX
|
||||
select MEMMAP_TRACEMEM
|
||||
select MEMMAP_TRACEMEM_TWOBANKS
|
||||
default n
|
||||
help
|
||||
Enables/disable application tracing module.
|
||||
config ESP32_APPTRACE_ENABLE
|
||||
bool
|
||||
depends on !ESP32_TRAX
|
||||
select MEMMAP_TRACEMEM
|
||||
select MEMMAP_TRACEMEM_TWOBANKS
|
||||
default n
|
||||
help
|
||||
Enables/disable application tracing module.
|
||||
|
||||
config ESP32_APPTRACE_LOCK_ENABLE
|
||||
bool
|
||||
default !SYSVIEW_ENABLE
|
||||
help
|
||||
Enables/disable application tracing module internal sync lock.
|
||||
config ESP32_APPTRACE_LOCK_ENABLE
|
||||
bool
|
||||
default !SYSVIEW_ENABLE
|
||||
help
|
||||
Enables/disable application tracing module internal sync lock.
|
||||
|
||||
config ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TMO
|
||||
int "Timeout for flushing last trace data to host on panic"
|
||||
depends on ESP32_APPTRACE_ENABLE
|
||||
range -1 5000
|
||||
default -1
|
||||
help
|
||||
Timeout for flushing last trace data to host in case of panic. In ms.
|
||||
Use -1 to disable timeout and wait forever.
|
||||
config ESP32_APPTRACE_ONPANIC_HOST_FLUSH_TMO
|
||||
int "Timeout for flushing last trace data to host on panic"
|
||||
depends on ESP32_APPTRACE_ENABLE
|
||||
range -1 5000
|
||||
default -1
|
||||
help
|
||||
Timeout for flushing last trace data to host in case of panic. In ms.
|
||||
Use -1 to disable timeout and wait forever.
|
||||
|
||||
config ESP32_APPTRACE_POSTMORTEM_FLUSH_TRAX_THRESH
|
||||
int "Threshold for flushing last trace data to host on panic"
|
||||
depends on ESP32_APPTRACE_DEST_TRAX
|
||||
range 0 16384
|
||||
default 0
|
||||
help
|
||||
Threshold for flushing last trace data to host on panic in post-mortem mode.
|
||||
This is minimal amount of data needed to perform flush. In bytes.
|
||||
config ESP32_APPTRACE_POSTMORTEM_FLUSH_TRAX_THRESH
|
||||
int "Threshold for flushing last trace data to host on panic"
|
||||
depends on ESP32_APPTRACE_DEST_TRAX
|
||||
range 0 16384
|
||||
default 0
|
||||
help
|
||||
Threshold for flushing last trace data to host on panic in post-mortem mode.
|
||||
This is minimal amount of data needed to perform flush. In bytes.
|
||||
|
||||
config ESP32_APPTRACE_PENDING_DATA_SIZE_MAX
|
||||
int "Size of the pending data buffer"
|
||||
depends on ESP32_APPTRACE_DEST_TRAX
|
||||
default 0
|
||||
help
|
||||
Size of the buffer for events in bytes. It is useful for buffering events from
|
||||
the time critical code (scheduler, ISRs etc). If this parameter is 0 then
|
||||
events will be discarded when main HW buffer is full.
|
||||
config ESP32_APPTRACE_PENDING_DATA_SIZE_MAX
|
||||
int "Size of the pending data buffer"
|
||||
depends on ESP32_APPTRACE_DEST_TRAX
|
||||
default 0
|
||||
help
|
||||
Size of the buffer for events in bytes. It is useful for buffering events from
|
||||
the time critical code (scheduler, ISRs etc). If this parameter is 0 then
|
||||
events will be discarded when main HW buffer is full.
|
||||
|
||||
menu "FreeRTOS SystemView Tracing"
|
||||
depends on ESP32_APPTRACE_ENABLE
|
||||
config SYSVIEW_ENABLE
|
||||
bool "SystemView Tracing Enable"
|
||||
depends on ESP32_APPTRACE_ENABLE
|
||||
default n
|
||||
help
|
||||
Enables supporrt for SEGGER SystemView tracing functionality.
|
||||
menu "FreeRTOS SystemView Tracing"
|
||||
depends on ESP32_APPTRACE_ENABLE
|
||||
config SYSVIEW_ENABLE
|
||||
bool "SystemView Tracing Enable"
|
||||
depends on ESP32_APPTRACE_ENABLE
|
||||
default n
|
||||
help
|
||||
Enables supporrt for SEGGER SystemView tracing functionality.
|
||||
|
||||
choice SYSVIEW_TS_SOURCE
|
||||
prompt "Timer to use as timestamp source"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default SYSVIEW_TS_SOURCE_CCOUNT if FREERTOS_UNICORE && !PM_ENABLE
|
||||
default SYSVIEW_TS_SOURCE_TIMER_00 if !FREERTOS_UNICORE && !PM_ENABLE
|
||||
default SYSVIEW_TS_SOURCE_ESP_TIMER if PM_ENABLE
|
||||
help
|
||||
SystemView needs to use a hardware timer as the source of timestamps
|
||||
when tracing. This option selects the timer for it.
|
||||
choice SYSVIEW_TS_SOURCE
|
||||
prompt "Timer to use as timestamp source"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default SYSVIEW_TS_SOURCE_CCOUNT if FREERTOS_UNICORE && !PM_ENABLE
|
||||
default SYSVIEW_TS_SOURCE_TIMER_00 if !FREERTOS_UNICORE && !PM_ENABLE
|
||||
default SYSVIEW_TS_SOURCE_ESP_TIMER if PM_ENABLE
|
||||
help
|
||||
SystemView needs to use a hardware timer as the source of timestamps
|
||||
when tracing. This option selects the timer for it.
|
||||
|
||||
config SYSVIEW_TS_SOURCE_CCOUNT
|
||||
bool "CPU cycle counter (CCOUNT)"
|
||||
depends on FREERTOS_UNICORE && !PM_ENABLE
|
||||
config SYSVIEW_TS_SOURCE_CCOUNT
|
||||
bool "CPU cycle counter (CCOUNT)"
|
||||
depends on FREERTOS_UNICORE && !PM_ENABLE
|
||||
|
||||
config SYSVIEW_TS_SOURCE_TIMER_00
|
||||
bool "Timer 0, Group 0"
|
||||
depends on !PM_ENABLE
|
||||
config SYSVIEW_TS_SOURCE_TIMER_00
|
||||
bool "Timer 0, Group 0"
|
||||
depends on !PM_ENABLE
|
||||
|
||||
config SYSVIEW_TS_SOURCE_TIMER_01
|
||||
bool "Timer 1, Group 0"
|
||||
depends on !PM_ENABLE
|
||||
config SYSVIEW_TS_SOURCE_TIMER_01
|
||||
bool "Timer 1, Group 0"
|
||||
depends on !PM_ENABLE
|
||||
|
||||
config SYSVIEW_TS_SOURCE_TIMER_10
|
||||
bool "Timer 0, Group 1"
|
||||
depends on !PM_ENABLE
|
||||
config SYSVIEW_TS_SOURCE_TIMER_10
|
||||
bool "Timer 0, Group 1"
|
||||
depends on !PM_ENABLE
|
||||
|
||||
config SYSVIEW_TS_SOURCE_TIMER_11
|
||||
bool "Timer 1, Group 1"
|
||||
depends on !PM_ENABLE
|
||||
config SYSVIEW_TS_SOURCE_TIMER_11
|
||||
bool "Timer 1, Group 1"
|
||||
depends on !PM_ENABLE
|
||||
|
||||
config SYSVIEW_TS_SOURCE_ESP_TIMER
|
||||
bool "esp_timer high resolution timer"
|
||||
config SYSVIEW_TS_SOURCE_ESP_TIMER
|
||||
bool "esp_timer high resolution timer"
|
||||
|
||||
endchoice
|
||||
endchoice
|
||||
|
||||
config SYSVIEW_MAX_TASKS
|
||||
int "Maximum supported tasks"
|
||||
depends on SYSVIEW_ENABLE
|
||||
range 1 64
|
||||
default 16
|
||||
help
|
||||
Configures maximum supported tasks in sysview debug
|
||||
config SYSVIEW_EVT_OVERFLOW_ENABLE
|
||||
bool "Trace Buffer Overflow Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Trace Buffer Overflow" event.
|
||||
|
||||
config SYSVIEW_EVT_OVERFLOW_ENABLE
|
||||
bool "Trace Buffer Overflow Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Trace Buffer Overflow" event.
|
||||
config SYSVIEW_EVT_ISR_ENTER_ENABLE
|
||||
bool "ISR Enter Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "ISR Enter" event.
|
||||
|
||||
config SYSVIEW_EVT_ISR_ENTER_ENABLE
|
||||
bool "ISR Enter Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "ISR Enter" event.
|
||||
config SYSVIEW_EVT_ISR_EXIT_ENABLE
|
||||
bool "ISR Exit Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "ISR Exit" event.
|
||||
|
||||
config SYSVIEW_EVT_ISR_EXIT_ENABLE
|
||||
bool "ISR Exit Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "ISR Exit" event.
|
||||
config SYSVIEW_EVT_ISR_TO_SCHEDULER_ENABLE
|
||||
bool "ISR Exit to Scheduler Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "ISR to Scheduler" event.
|
||||
|
||||
config SYSVIEW_EVT_ISR_TO_SCHEDULER_ENABLE
|
||||
bool "ISR Exit to Scheduler Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "ISR to Scheduler" event.
|
||||
config SYSVIEW_EVT_TASK_START_EXEC_ENABLE
|
||||
bool "Task Start Execution Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Start Execution" event.
|
||||
|
||||
config SYSVIEW_EVT_TASK_START_EXEC_ENABLE
|
||||
bool "Task Start Execution Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Start Execution" event.
|
||||
config SYSVIEW_EVT_TASK_STOP_EXEC_ENABLE
|
||||
bool "Task Stop Execution Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Stop Execution" event.
|
||||
|
||||
config SYSVIEW_EVT_TASK_STOP_EXEC_ENABLE
|
||||
bool "Task Stop Execution Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Stop Execution" event.
|
||||
config SYSVIEW_EVT_TASK_START_READY_ENABLE
|
||||
bool "Task Start Ready State Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Start Ready State" event.
|
||||
|
||||
config SYSVIEW_EVT_TASK_START_READY_ENABLE
|
||||
bool "Task Start Ready State Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Start Ready State" event.
|
||||
config SYSVIEW_EVT_TASK_STOP_READY_ENABLE
|
||||
bool "Task Stop Ready State Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Stop Ready State" event.
|
||||
|
||||
config SYSVIEW_EVT_TASK_STOP_READY_ENABLE
|
||||
bool "Task Stop Ready State Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Stop Ready State" event.
|
||||
config SYSVIEW_EVT_TASK_CREATE_ENABLE
|
||||
bool "Task Create Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Create" event.
|
||||
|
||||
config SYSVIEW_EVT_TASK_CREATE_ENABLE
|
||||
bool "Task Create Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Create" event.
|
||||
config SYSVIEW_EVT_TASK_TERMINATE_ENABLE
|
||||
bool "Task Terminate Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Terminate" event.
|
||||
|
||||
config SYSVIEW_EVT_TASK_TERMINATE_ENABLE
|
||||
bool "Task Terminate Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Task Terminate" event.
|
||||
config SYSVIEW_EVT_IDLE_ENABLE
|
||||
bool "System Idle Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "System Idle" event.
|
||||
|
||||
config SYSVIEW_EVT_IDLE_ENABLE
|
||||
bool "System Idle Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "System Idle" event.
|
||||
config SYSVIEW_EVT_TIMER_ENTER_ENABLE
|
||||
bool "Timer Enter Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Timer Enter" event.
|
||||
|
||||
config SYSVIEW_EVT_TIMER_ENTER_ENABLE
|
||||
bool "Timer Enter Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Timer Enter" event.
|
||||
|
||||
config SYSVIEW_EVT_TIMER_EXIT_ENABLE
|
||||
bool "Timer Exit Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Timer Exit" event.
|
||||
|
||||
endmenu
|
||||
|
||||
config ESP32_GCOV_ENABLE
|
||||
bool "GCOV to Host Enable"
|
||||
depends on ESP32_DEBUG_STUBS_ENABLE && ESP32_APPTRACE_ENABLE && !SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables support for GCOV data transfer to host.
|
||||
config SYSVIEW_EVT_TIMER_EXIT_ENABLE
|
||||
bool "Timer Exit Event"
|
||||
depends on SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables "Timer Exit" event.
|
||||
|
||||
endmenu
|
||||
|
||||
config ESP32_GCOV_ENABLE
|
||||
bool "GCOV to Host Enable"
|
||||
depends on ESP32_DEBUG_STUBS_ENABLE && ESP32_APPTRACE_ENABLE && !SYSVIEW_ENABLE
|
||||
default y
|
||||
help
|
||||
Enables support for GCOV data transfer to host.
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
// |<------------------------------------------->|TRAX_CTRL_REGS|<---->|
|
||||
// ----------------
|
||||
|
||||
// In general tracing goes in the following way. User application requests tracing module to send some data by calling esp_apptrace_buffer_get(),
|
||||
// In general tracing goes in the following way. User aplication requests tracing module to send some data by calling esp_apptrace_buffer_get(),
|
||||
// module allocates necessary buffer in current input trace block. Then user fills received buffer with data and calls esp_apptrace_buffer_put().
|
||||
// When current input trace block is filled with app data it is exposed to host and the second block becomes input one and buffer filling restarts.
|
||||
// While target application fills one TRAX block host reads another one via JTAG.
|
||||
@@ -62,7 +62,7 @@
|
||||
// 21..15 bits - trace memory block transfer ID. Block counter. It can overflow. Updated by target, host should not modify it. Actually can be 2 bits;
|
||||
// 22 bit - 'host data present' flag. If set to one there is data from host, otherwise - no host data;
|
||||
// 23 bit - 'host connected' flag. If zero then host is not connected and tracing module works in post-mortem mode, otherwise in streaming mode;
|
||||
// - Status register uses TRAX_TRIGGERPC as storage. If this register is not zero then current CPU is changing TRAX registers and
|
||||
// - Status register uses TRAX_TRIGGERPC as storage. If this register is not zero then currentlly CPU is changing TRAX registers and
|
||||
// this register holds address of the instruction which application will execute when it finishes with those registers modifications.
|
||||
// See 'Targets Connection' setion for details.
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
// 4.1 Trace Memory Blocks
|
||||
// -----------------------
|
||||
|
||||
// Communication is controlled via special register. Host periodically polls control register on each core to find out if there are any data available.
|
||||
// Communication is controlled via special register. Host periodically polls control register on each core to find out if there are any data avalable.
|
||||
// When current input memory block is filled it is exposed to host and 'block_len' and 'block_id' fields are updated in the control register.
|
||||
// Host reads new register value and according to it's value starts reading data from exposed block. Meanwhile target starts filling another trace block.
|
||||
// When host finishes reading the block it clears 'block_len' field in control register indicating to the target that it is ready to accept the next one.
|
||||
@@ -102,9 +102,9 @@
|
||||
// multithreading environment it can happen that task/ISR which copies data is preempted by another high prio task/ISR. So it is possible situation
|
||||
// that task/ISR will fail to complete filling its data chunk before the whole trace block is exposed to the host. To handle such conditions tracing
|
||||
// module prepends all user data chunks with header which contains allocated buffer size and actual data length within it. OpenOCD command
|
||||
// which reads application traces reports error when it reads incomplete user data block.
|
||||
// Data which are transffered from host to target are also prepended with a header. Down channel data header is simple and consists of one two bytes field
|
||||
// containing length of host data following the header.
|
||||
// which reads application traces reports error when it reads incompleted user data block.
|
||||
// Data which are transfered from host to target are also prepended with a header. Down channel data header is simple and consists of one two bytes field
|
||||
// containing length of host data following the heder.
|
||||
|
||||
// 4.3 Data Buffering
|
||||
// ------------------
|
||||
@@ -141,18 +141,20 @@
|
||||
// So no local task switch occurs when mutex is locked. But this does not apply to tasks on another CPU.
|
||||
// WARNING: Priority inversion can happen when low prio task works on one CPU and medium and high prio tasks work on another.
|
||||
// WARNING: Care must be taken when selecting timeout values for trace calls from ISRs. Tracing module does not care about watchdogs when waiting
|
||||
// on internal locks and for host to complete previous block reading, so if timeout value exceeds watchdog's one it can lead to the system reboot.
|
||||
// on internal locks and for host to complete previous block reading, so if timeout value exceedes watchdog's one it can lead to the system reboot.
|
||||
|
||||
// 6. Timeouts
|
||||
// ===========
|
||||
|
||||
// Timeout mechanism is based on xthal_get_ccount() routine and supports timeout values in microseconds.
|
||||
// Timeout mechanism is based on xthal_get_ccount() routine and supports timeout values in micorseconds.
|
||||
// There are two situations when task/ISR can be delayed by tracing API call. Timeout mechanism takes into account both conditions:
|
||||
// - Trace data are locked by another task/ISR. When wating on trace data lock.
|
||||
// - Current TRAX memory input block is full when working in streaming mode (host is connected). When waiting for host to complete previous block reading.
|
||||
// When wating for any of above conditions xthal_get_ccount() is called periodically to calculate time elapsed from trace API routine entry. When elapsed
|
||||
// time exceeds specified timeout value operation is canceled and ESP_ERR_TIMEOUT code is returned.
|
||||
|
||||
// ALSO SEE example usage of application tracing module in 'components/app_trace/README.rst'
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
#include "soc/soc.h"
|
||||
@@ -170,6 +172,7 @@
|
||||
|
||||
#define ESP_APPTRACE_PRINT_LOCK 0
|
||||
|
||||
#define LOG_LOCAL_LEVEL CONFIG_LOG_DEFAULT_LEVEL
|
||||
#include "esp_log.h"
|
||||
const static char *TAG = "esp_apptrace";
|
||||
|
||||
|
||||
@@ -27,5 +27,3 @@ COMPONENT_SRCDIRS += \
|
||||
else
|
||||
COMPONENT_SRCDIRS += gcov
|
||||
endif
|
||||
|
||||
COMPONENT_ADD_LDFRAGMENTS += linker.lf
|
||||
|
||||
@@ -51,7 +51,7 @@ void esp_apptrace_down_buffer_config(uint8_t *buf, uint32_t size);
|
||||
*
|
||||
* @param dest Indicates HW interface to send data.
|
||||
* @param size Size of data to write to trace buffer.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* @return non-NULL on success, otherwise NULL.
|
||||
*/
|
||||
@@ -63,7 +63,7 @@ uint8_t *esp_apptrace_buffer_get(esp_apptrace_dest_t dest, uint32_t size, uint32
|
||||
*
|
||||
* @param dest Indicates HW interface to send data. Should be identical to the same parameter in call to esp_apptrace_buffer_get.
|
||||
* @param ptr Address of trace buffer to release. Should be the value returned by call to esp_apptrace_buffer_get.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
@@ -75,7 +75,7 @@ esp_err_t esp_apptrace_buffer_put(esp_apptrace_dest_t dest, uint8_t *ptr, uint32
|
||||
* @param dest Indicates HW interface to send data.
|
||||
* @param data Address of data to write to trace buffer.
|
||||
* @param size Size of data to write to trace buffer.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
@@ -85,7 +85,7 @@ esp_err_t esp_apptrace_write(esp_apptrace_dest_t dest, const void *data, uint32_
|
||||
* @brief vprintf-like function to sent log messages to host via specified HW interface.
|
||||
*
|
||||
* @param dest Indicates HW interface to send data.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
* @param fmt Address of format string.
|
||||
* @param ap List of arguments.
|
||||
*
|
||||
@@ -107,7 +107,7 @@ int esp_apptrace_vprintf(const char *fmt, va_list ap);
|
||||
* @brief Flushes remaining data in trace buffer to host.
|
||||
*
|
||||
* @param dest Indicates HW interface to flush data on.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
@@ -119,7 +119,7 @@ esp_err_t esp_apptrace_flush(esp_apptrace_dest_t dest, uint32_t tmo);
|
||||
*
|
||||
* @param dest Indicates HW interface to flush data on.
|
||||
* @param min_sz Threshold for flushing data. If current filling level is above this value, data will be flushed. TRAX destinations only.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
@@ -131,31 +131,31 @@ esp_err_t esp_apptrace_flush_nolock(esp_apptrace_dest_t dest, uint32_t min_sz, u
|
||||
* @param dest Indicates HW interface to read the data on.
|
||||
* @param data Address of buffer to put data from trace buffer.
|
||||
* @param size Pointer to store size of read data. Before call to this function pointed memory must hold requested size of data
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
esp_err_t esp_apptrace_read(esp_apptrace_dest_t dest, void *data, uint32_t *size, uint32_t tmo);
|
||||
|
||||
/**
|
||||
* @brief Retrieves incoming data buffer if any.
|
||||
* @brief Rertrieves incoming data buffer if any.
|
||||
* After data in buffer are processed esp_apptrace_down_buffer_put must be called to indicate it.
|
||||
*
|
||||
* @param dest Indicates HW interface to receive data.
|
||||
* @param size Address to store size of available data in down buffer. Must be initialized with requested value.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param size Address to store size of available data in down buffer. Must be initializaed with requested value.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* @return non-NULL on success, otherwise NULL.
|
||||
*/
|
||||
uint8_t *esp_apptrace_down_buffer_get(esp_apptrace_dest_t dest, uint32_t *size, uint32_t tmo);
|
||||
|
||||
/**
|
||||
* @brief Indicates that the data in down buffer are processed.
|
||||
* @brief Indicates that the data in down buffer are processesd.
|
||||
* This function is a counterpart of and must be preceeded by esp_apptrace_down_buffer_get.
|
||||
*
|
||||
* @param dest Indicates HW interface to receive data. Should be identical to the same parameter in call to esp_apptrace_down_buffer_get.
|
||||
* @param ptr Address of trace buffer to release. Should be the value returned by call to esp_apptrace_down_buffer_get.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinitely.
|
||||
* @param tmo Timeout for operation (in us). Use ESP_APPTRACE_TMO_INFINITE to wait indefinetly.
|
||||
*
|
||||
* @return ESP_OK on success, otherwise see esp_err_t
|
||||
*/
|
||||
@@ -247,7 +247,7 @@ int esp_apptrace_ftell(esp_apptrace_dest_t dest, void *stream);
|
||||
|
||||
/**
|
||||
* @brief Indicates to the host that all file operations are completed.
|
||||
* This function should be called after all file operations are finished and
|
||||
* This function should be called after all file operations are finished and
|
||||
* indicate to the host that it can perform cleanup operations (close open files etc.).
|
||||
*
|
||||
* @param dest Indicates HW interface to use.
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
[mapping]
|
||||
archive: libapp_trace.a
|
||||
entries:
|
||||
* (noflash)
|
||||
|
||||
[mapping]
|
||||
archive: libdriver.a
|
||||
entries:
|
||||
: SYSVIEW_TS_SOURCE_TIMER_00 = y || SYSVIEW_TS_SOURCE_TIMER_01 = y
|
||||
|| SYSVIEW_TS_SOURCE_TIMER_10 = y || SYSVIEW_TS_SOURCE_TIMER_11 = y
|
||||
timer (noflash)
|
||||
|
||||
@@ -166,11 +166,10 @@ Revision: $Rev: 5927 $
|
||||
#define SEGGER_SYSVIEW_GET_INTERRUPT_ID() SEGGER_SYSVIEW_X_GetInterruptId() // Get the currently active interrupt Id from the user-provided function.
|
||||
#endif
|
||||
|
||||
unsigned SEGGER_SYSVIEW_X_SysView_Lock();
|
||||
void SEGGER_SYSVIEW_X_SysView_Unlock(unsigned int_state);
|
||||
// to be recursive save IRQ status on the stack of the caller
|
||||
#define SEGGER_SYSVIEW_LOCK() unsigned _SYSVIEW_int_state = SEGGER_SYSVIEW_X_SysView_Lock()
|
||||
#define SEGGER_SYSVIEW_UNLOCK() SEGGER_SYSVIEW_X_SysView_Unlock(_SYSVIEW_int_state)
|
||||
void SEGGER_SYSVIEW_X_SysView_Lock();
|
||||
void SEGGER_SYSVIEW_X_SysView_Unlock();
|
||||
#define SEGGER_SYSVIEW_LOCK() SEGGER_SYSVIEW_X_SysView_Lock()
|
||||
#define SEGGER_SYSVIEW_UNLOCK() SEGGER_SYSVIEW_X_SysView_Unlock()
|
||||
|
||||
#endif // SEGGER_SYSVIEW_CONF_H
|
||||
|
||||
|
||||
@@ -2368,7 +2368,7 @@ void SEGGER_SYSVIEW_RegisterModule(SEGGER_SYSVIEW_MODULE* pModule) {
|
||||
_pFirstModule = pModule;
|
||||
_NumModules++;
|
||||
}
|
||||
SEGGER_SYSVIEW_SendModule(_NumModules-1);
|
||||
SEGGER_SYSVIEW_SendModule(0);
|
||||
if (pModule->pfSendModuleDesc) {
|
||||
pModule->pfSendModuleDesc();
|
||||
}
|
||||
|
||||
@@ -337,18 +337,15 @@ void SEGGER_SYSVIEW_X_RTT_Unlock()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned SEGGER_SYSVIEW_X_SysView_Lock()
|
||||
void SEGGER_SYSVIEW_X_SysView_Lock()
|
||||
{
|
||||
esp_apptrace_tmo_t tmo;
|
||||
esp_apptrace_tmo_init(&tmo, SEGGER_LOCK_WAIT_TMO);
|
||||
esp_apptrace_lock_take(&s_sys_view_lock, &tmo);
|
||||
// to be recursive save IRQ status on the stack of the caller to keep it from overwriting
|
||||
return s_sys_view_lock.int_state;
|
||||
}
|
||||
|
||||
void SEGGER_SYSVIEW_X_SysView_Unlock(unsigned int_state)
|
||||
void SEGGER_SYSVIEW_X_SysView_Unlock()
|
||||
{
|
||||
s_sys_view_lock.int_state = int_state;
|
||||
esp_apptrace_lock_give(&s_sys_view_lock);
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ Notes:
|
||||
#define portSTACK_GROWTH ( -1 )
|
||||
#endif
|
||||
|
||||
#define SYSVIEW_FREERTOS_MAX_NOF_TASKS CONFIG_SYSVIEW_MAX_TASKS
|
||||
#define SYSVIEW_FREERTOS_MAX_NOF_TASKS 16
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
|
||||
@@ -1,40 +1,17 @@
|
||||
set(COMPONENT_SRCS "esp_ota_ops.c"
|
||||
"esp_app_desc.c")
|
||||
set(COMPONENT_SRCS "esp_ota_ops.c")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "include")
|
||||
|
||||
set(COMPONENT_REQUIRES spi_flash partition_table bootloader_support)
|
||||
set(COMPONENT_REQUIRES spi_flash partition_table)
|
||||
set(COMPONENT_PRIV_REQUIRES bootloader_support)
|
||||
|
||||
register_component()
|
||||
|
||||
# esp_app_desc structure is added as an undefined symbol because otherwise the
|
||||
# linker will ignore this structure as it has no other files depending on it.
|
||||
target_link_libraries(${COMPONENT_TARGET} "-u esp_app_desc")
|
||||
|
||||
# cut PROJECT_VER and PROJECT_NAME to required 32 characters.
|
||||
string(SUBSTRING "${PROJECT_VER}" 0 31 PROJECT_VER_CUT)
|
||||
string(SUBSTRING "${PROJECT_NAME}" 0 31 PROJECT_NAME_CUT)
|
||||
|
||||
set_source_files_properties(
|
||||
SOURCE "esp_app_desc.c"
|
||||
PROPERTIES COMPILE_DEFINITIONS
|
||||
"PROJECT_VER=\"${PROJECT_VER_CUT}\"; PROJECT_NAME=\"${PROJECT_NAME_CUT}\"")
|
||||
|
||||
# Add custom target for generating empty otadata partition for flashing
|
||||
if(OTADATA_PARTITION_OFFSET AND OTADATA_PARTITION_SIZE)
|
||||
add_custom_command(OUTPUT "${IDF_BUILD_ARTIFACTS_DIR}/${BLANK_OTADATA_FILE}"
|
||||
COMMAND ${PYTHON} ${IDF_PATH}/components/partition_table/parttool.py
|
||||
--partition-type data --partition-subtype ota -q
|
||||
--partition-table-file ${PARTITION_CSV_PATH} generate_blank_partition_file
|
||||
--output "${IDF_BUILD_ARTIFACTS_DIR}/${BLANK_OTADATA_FILE}")
|
||||
if(${OTADATA_PARTITION_OFFSET})
|
||||
add_custom_command(OUTPUT "${PROJECT_BINARY_DIR}/${BLANK_OTADATA_FILE}"
|
||||
COMMAND ${PYTHON} ${CMAKE_CURRENT_SOURCE_DIR}/gen_empty_partition.py
|
||||
--size ${OTADATA_PARTITION_SIZE} "${PROJECT_BINARY_DIR}/${BLANK_OTADATA_FILE}")
|
||||
|
||||
add_custom_target(blank_ota_data ALL DEPENDS "${IDF_BUILD_ARTIFACTS_DIR}/${BLANK_OTADATA_FILE}")
|
||||
add_custom_target(blank_ota_data ALL DEPENDS "${PROJECT_BINARY_DIR}/${BLANK_OTADATA_FILE}")
|
||||
add_dependencies(flash blank_ota_data)
|
||||
endif()
|
||||
|
||||
set(otatool_py ${PYTHON} ${COMPONENT_PATH}/otatool.py)
|
||||
|
||||
add_custom_target(read_otadata DEPENDS "${PARTITION_CSV_PATH}"
|
||||
COMMAND ${otatool_py} --partition-table-file ${PARTITION_CSV_PATH} read_otadata)
|
||||
|
||||
add_custom_target(erase_otadata DEPENDS "${PARTITION_CSV_PATH}"
|
||||
COMMAND ${otatool_py} --partition-table-file ${PARTITION_CSV_PATH} erase_otadata)
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
menu "Application manager"
|
||||
|
||||
config APP_COMPILE_TIME_DATE
|
||||
bool "Use time/date stamp for app"
|
||||
default y
|
||||
help
|
||||
If set, then the app will be built with the current time/date stamp. It is stored in the app description
|
||||
structure. If not set, time/date stamp will be excluded from app image. This can be useful for getting the
|
||||
same binary image files made from the same source, but at different times.
|
||||
|
||||
config APP_EXCLUDE_PROJECT_VER_VAR
|
||||
bool "Exclude PROJECT_VER from firmware image"
|
||||
default n
|
||||
help
|
||||
The PROJECT_VER variable from the build system will not affect the firmware image.
|
||||
This value will not be contained in the esp_app_desc structure.
|
||||
|
||||
config APP_EXCLUDE_PROJECT_NAME_VAR
|
||||
bool "Exclude PROJECT_NAME from firmware image"
|
||||
default n
|
||||
help
|
||||
The PROJECT_NAME variable from the build system will not affect the firmware image.
|
||||
This value will not be contained in the esp_app_desc structure.
|
||||
|
||||
config APP_RETRIEVE_LEN_ELF_SHA
|
||||
int "The length of APP ELF SHA is stored in RAM(chars)"
|
||||
default 16
|
||||
range 8 64
|
||||
help
|
||||
At startup, the app will read this many hex characters from the embedded APP ELF SHA-256 hash value
|
||||
and store it in static RAM. This ensures the app ELF SHA-256 value is always available
|
||||
if it needs to be printed by the panic handler code.
|
||||
Changing this value will change the size of a static buffer, in bytes.
|
||||
|
||||
endmenu # "Application manager"
|
||||
@@ -1,49 +1,60 @@
|
||||
# Generate partition binary
|
||||
#
|
||||
.PHONY: blank_ota_data erase_otadata read_otadata
|
||||
.PHONY: dump_otadata erase_ota blank_ota_data
|
||||
|
||||
OTATOOL_PY := $(PYTHON) $(COMPONENT_PATH)/otatool.py
|
||||
PARTTOOL_PY := $(PYTHON) $(IDF_PATH)/components/partition_table/parttool.py
|
||||
|
||||
# Generate blank partition file
|
||||
GEN_EMPTY_PART := $(PYTHON) $(COMPONENT_PATH)/gen_empty_partition.py
|
||||
BLANK_OTA_DATA_FILE = $(BUILD_DIR_BASE)/ota_data_initial.bin
|
||||
|
||||
# Copy PARTITION_TABLE_CSV_PATH definition here from $IDF_PATH/components/partition_table/Makefile.projbuild
|
||||
# to avoid undefined variables warning for PARTITION_TABLE_CSV_PATH
|
||||
ifndef PARTITION_TABLE_CSV_PATH
|
||||
PARTITION_TABLE_ROOT := $(call dequote,$(if $(CONFIG_PARTITION_TABLE_CUSTOM),$(PROJECT_PATH),$(IDF_PATH)/components/partition_table))
|
||||
PARTITION_TABLE_CSV_PATH := $(call dequote,$(abspath $(PARTITION_TABLE_ROOT)/$(call dequote,$(CONFIG_PARTITION_TABLE_FILENAME))))
|
||||
endif
|
||||
PARTITION_TABLE_LEN := 0xC00
|
||||
OTADATA_LEN := 0x2000
|
||||
|
||||
$(BLANK_OTA_DATA_FILE): partition_table_get_info $(PARTITION_TABLE_CSV_PATH) | check_python_dependencies
|
||||
$(shell if [ "$(OTA_DATA_OFFSET)" != "" ] && [ "$(OTA_DATA_SIZE)" != "" ]; then \
|
||||
$(PARTTOOL_PY) --partition-type data --partition-subtype ota --partition-table-file $(PARTITION_TABLE_CSV_PATH) \
|
||||
-q generate_blank_partition_file --output $(BLANK_OTA_DATA_FILE); \
|
||||
fi; )
|
||||
$(eval BLANK_OTA_DATA_FILE = $(shell if [ "$(OTA_DATA_OFFSET)" != "" ] && [ "$(OTA_DATA_SIZE)" != "" ]; then \
|
||||
echo $(BLANK_OTA_DATA_FILE); else echo " "; fi) )
|
||||
PARTITION_TABLE_ONCHIP_BIN_PATH := $(call dequote,$(abspath $(BUILD_DIR_BASE)))
|
||||
PARTITION_TABLE_ONCHIP_BIN_NAME := "onchip_partition.bin"
|
||||
OTADATA_ONCHIP_BIN_NAME := "onchip_otadata.bin"
|
||||
|
||||
blank_ota_data: $(BLANK_OTA_DATA_FILE)
|
||||
PARTITION_TABLE_ONCHIP_BIN := $(PARTITION_TABLE_ONCHIP_BIN_PATH)/$(call dequote,$(PARTITION_TABLE_ONCHIP_BIN_NAME))
|
||||
OTADATA_ONCHIP_BIN := $(PARTITION_TABLE_ONCHIP_BIN_PATH)/$(call dequote,$(OTADATA_ONCHIP_BIN_NAME))
|
||||
|
||||
PARTITION_TABLE_GET_BIN_CMD = $(ESPTOOLPY_SERIAL) read_flash $(PARTITION_TABLE_OFFSET) $(PARTITION_TABLE_LEN) $(PARTITION_TABLE_ONCHIP_BIN)
|
||||
OTADATA_GET_BIN_CMD = $(ESPTOOLPY_SERIAL) read_flash $(OTADATA_OFFSET) $(OTADATA_LEN) $(OTADATA_ONCHIP_BIN)
|
||||
|
||||
GEN_OTADATA = $(IDF_PATH)/components/app_update/dump_otadata.py
|
||||
ERASE_OTADATA_CMD = $(ESPTOOLPY_SERIAL) erase_region $(OTADATA_OFFSET) $(OTADATA_LEN)
|
||||
|
||||
# If there is no otadata partition, both OTA_DATA_OFFSET and BLANK_OTA_DATA_FILE
|
||||
# expand to empty values.
|
||||
ESPTOOL_ALL_FLASH_ARGS += $(OTA_DATA_OFFSET) $(BLANK_OTA_DATA_FILE)
|
||||
|
||||
erase_otadata: $(PARTITION_TABLE_CSV_PATH) partition_table_get_info | check_python_dependencies
|
||||
$(OTATOOL_PY) --partition-table-file $(PARTITION_TABLE_CSV_PATH) erase_otadata
|
||||
$(PARTITION_TABLE_ONCHIP_BIN):
|
||||
$(PARTITION_TABLE_GET_BIN_CMD)
|
||||
|
||||
read_otadata: $(PARTITION_TABLE_CSV_PATH) partition_table_get_info | check_python_dependencies
|
||||
$(OTATOOL_PY) --partition-table-file $(PARTITION_TABLE_CSV_PATH) read_otadata
|
||||
onchip_otadata_get_info: $(PARTITION_TABLE_ONCHIP_BIN)
|
||||
$(eval OTADATA_OFFSET:=$(shell $(GET_PART_INFO) --type data --subtype ota --offset $(PARTITION_TABLE_ONCHIP_BIN)))
|
||||
@echo $(if $(OTADATA_OFFSET), $(shell export OTADATA_OFFSET), $(shell rm -f $(PARTITION_TABLE_ONCHIP_BIN));$(error "ERROR: ESP32 does not have otadata partition."))
|
||||
|
||||
erase_ota: erase_otadata
|
||||
@echo "WARNING: erase_ota is deprecated. Use erase_otadata instead."
|
||||
$(OTADATA_ONCHIP_BIN):
|
||||
$(OTADATA_GET_BIN_CMD)
|
||||
|
||||
dump_otadata: onchip_otadata_get_info $(OTADATA_ONCHIP_BIN) $(PARTITION_TABLE_ONCHIP_BIN)
|
||||
@echo "otadata retrieved. Contents:"
|
||||
@echo $(SEPARATOR)
|
||||
$(GEN_OTADATA) $(OTADATA_ONCHIP_BIN)
|
||||
@echo $(SEPARATOR)
|
||||
rm -f $(PARTITION_TABLE_ONCHIP_BIN)
|
||||
rm -f $(OTADATA_ONCHIP_BIN)
|
||||
|
||||
$(BLANK_OTA_DATA_FILE): partition_table_get_info
|
||||
$(GEN_EMPTY_PART) --size $(OTA_DATA_SIZE) $(BLANK_OTA_DATA_FILE)
|
||||
$(eval BLANK_OTA_DATA_FILE = $(shell if [ $(OTA_DATA_SIZE) != 0 ]; then echo $(BLANK_OTA_DATA_FILE); else echo " "; fi) )
|
||||
|
||||
blank_ota_data: $(BLANK_OTA_DATA_FILE)
|
||||
|
||||
erase_ota: partition_table_get_info | check_python_dependencies
|
||||
@echo $(if $(OTA_DATA_OFFSET), "Erase ota_data [addr=$(OTA_DATA_OFFSET) size=$(OTA_DATA_SIZE)] ...", $(error "ERROR: Partition table does not have ota_data partition."))
|
||||
$(ESPTOOLPY_SERIAL) erase_region $(OTA_DATA_OFFSET) $(OTA_DATA_SIZE)
|
||||
|
||||
all: blank_ota_data
|
||||
flash: blank_ota_data
|
||||
|
||||
TMP_DEFINES := $(BUILD_DIR_BASE)/app_update/tmp_cppflags.txt
|
||||
export TMP_DEFINES
|
||||
|
||||
clean:
|
||||
rm -f $(BLANK_OTA_DATA_FILE)
|
||||
rm -f $(TMP_DEFINES)
|
||||
|
||||
@@ -3,54 +3,3 @@
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
|
||||
# esp_app_desc structure is added as an undefined symbol because otherwise the
|
||||
# linker will ignore this structure as it has no other files depending on it.
|
||||
COMPONENT_ADD_LDFLAGS += -u esp_app_desc
|
||||
|
||||
ifndef IS_BOOTLOADER_BUILD
|
||||
GET_PROJECT_VER ?=
|
||||
ifeq ("${PROJECT_VER}", "")
|
||||
ifeq ("$(wildcard ${PROJECT_PATH}/version.txt)","")
|
||||
|
||||
GET_PROJECT_VER := $(shell cd ${PROJECT_PATH} && git describe --always --tags --dirty 2> /dev/null)
|
||||
ifeq ("${GET_PROJECT_VER}", "")
|
||||
GET_PROJECT_VER := "1"
|
||||
$(info Project is not inside a git repository, will not use 'git describe' to determine PROJECT_VER.)
|
||||
endif
|
||||
|
||||
else
|
||||
# read from version.txt
|
||||
GET_PROJECT_VER := $(shell cat ${PROJECT_PATH}/version.txt)
|
||||
endif
|
||||
endif
|
||||
# If ``PROJECT_VER`` variable set in project Makefile file, its value will be used.
|
||||
# Else, if the ``$PROJECT_PATH/version.txt`` exists, its contents will be used as ``PROJECT_VER``.
|
||||
# Else, if the project is located inside a Git repository, the output of git describe will be used.
|
||||
# Otherwise, ``PROJECT_VER`` will be "1".
|
||||
|
||||
ifeq ("${PROJECT_VER}", "")
|
||||
PROJECT_VER:= $(GET_PROJECT_VER)
|
||||
else
|
||||
PROJECT_VER:= $(PROJECT_VER)
|
||||
endif
|
||||
|
||||
# cut PROJECT_VER and PROJECT_NAME to required 32 characters.
|
||||
PROJECT_VER_CUT := $(shell echo "$(PROJECT_VER)" | cut -c 1-31)
|
||||
PROJECT_NAME_CUT := $(shell echo "$(PROJECT_NAME)" | cut -c 1-31)
|
||||
|
||||
$(info App "$(PROJECT_NAME_CUT)" version: $(PROJECT_VER_CUT))
|
||||
|
||||
NEW_DEFINES:= "$(PROJECT_VER_CUT) $(PROJECT_NAME_CUT) $(IDF_VER)"
|
||||
ifeq ("$(wildcard ${TMP_DEFINES})","")
|
||||
OLD_DEFINES:= ""
|
||||
else
|
||||
OLD_DEFINES:= "$(shell cat $(TMP_DEFINES))"
|
||||
endif
|
||||
|
||||
# If NEW_DEFINES (PROJECT_VER, PROJECT_NAME) were changed then rebuild only esp_app_desc.
|
||||
ifneq (${NEW_DEFINES}, ${OLD_DEFINES})
|
||||
$(shell echo $(NEW_DEFINES) > $(TMP_DEFINES); rm -f esp_app_desc.o;)
|
||||
endif
|
||||
|
||||
esp_app_desc.o: CPPFLAGS += -D PROJECT_VER=\""$(PROJECT_VER_CUT)"\" -D PROJECT_NAME=\""$(PROJECT_NAME_CUT)"\"
|
||||
endif
|
||||
|
||||
88
components/app_update/dump_otadata.py
Executable file
88
components/app_update/dump_otadata.py
Executable file
@@ -0,0 +1,88 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# gen_otadata prints info about the otadata partition.
|
||||
#
|
||||
# Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http:#www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from __future__ import print_function, division
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import struct
|
||||
import sys
|
||||
import hashlib
|
||||
import binascii
|
||||
|
||||
__version__ = '1.0'
|
||||
|
||||
quiet = False
|
||||
|
||||
def status(msg):
|
||||
""" Print status message to stderr """
|
||||
if not quiet:
|
||||
critical(msg)
|
||||
|
||||
def critical(msg):
|
||||
""" Print critical message to stderr """
|
||||
if not quiet:
|
||||
sys.stderr.write(msg)
|
||||
sys.stderr.write('\n')
|
||||
|
||||
def little_endian(buff, offset):
|
||||
data = buff[offset:offset+4]
|
||||
data.reverse()
|
||||
data = ''.join(data)
|
||||
return data
|
||||
|
||||
def main():
|
||||
global quiet
|
||||
parser = argparse.ArgumentParser(description='Prints otadata partition in human readable form.')
|
||||
|
||||
parser.add_argument('--quiet', '-q', help="Don't print status messages to stderr", action='store_true')
|
||||
|
||||
search_type = parser.add_mutually_exclusive_group()
|
||||
|
||||
parser.add_argument('input', help='Path to binary file containing otadata partition to parse.',
|
||||
type=argparse.FileType('rb'))
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
quiet = args.quiet
|
||||
|
||||
input = args.input.read()
|
||||
|
||||
hex_input_0 = binascii.hexlify(input)
|
||||
hex_input_0 = map(''.join, zip(*[iter(hex_input_0)]*2))
|
||||
hex_input_1 = binascii.hexlify(input[4096:])
|
||||
hex_input_1 = map(''.join, zip(*[iter(hex_input_1)]*2))
|
||||
|
||||
print("\t%11s\t%8s |\t%8s\t%8s" %("OTA_SEQ", "CRC", "OTA_SEQ", "CRC"))
|
||||
print("Firmware: 0x%s \t 0x%s |\t0x%s \t 0x%s" % (little_endian(hex_input_0, 0), little_endian(hex_input_0, 28), \
|
||||
little_endian(hex_input_1, 0), little_endian(hex_input_1, 28)))
|
||||
class InputError(RuntimeError):
|
||||
def __init__(self, e):
|
||||
super(InputError, self).__init__(e)
|
||||
|
||||
class ValidationError(InputError):
|
||||
def __init__(self, partition, message):
|
||||
super(ValidationError, self).__init__(
|
||||
"Partition %s invalid: %s" % (partition.name, message))
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
r = main()
|
||||
sys.exit(r)
|
||||
except InputError as e:
|
||||
print(e, file=sys.stderr)
|
||||
sys.exit(2)
|
||||
@@ -1,107 +0,0 @@
|
||||
// Copyright 2017-2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <assert.h>
|
||||
#include <sys/param.h>
|
||||
#include "esp_ota_ops.h"
|
||||
#include "esp_attr.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
// Application version info
|
||||
const __attribute__((section(".rodata_desc"))) esp_app_desc_t esp_app_desc = {
|
||||
.magic_word = ESP_APP_DESC_MAGIC_WORD,
|
||||
#ifdef CONFIG_APP_EXCLUDE_PROJECT_VER_VAR
|
||||
.version = "",
|
||||
#else
|
||||
.version = PROJECT_VER,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR
|
||||
.project_name = "",
|
||||
#else
|
||||
.project_name = PROJECT_NAME,
|
||||
#endif
|
||||
.idf_ver = IDF_VER,
|
||||
|
||||
#ifdef CONFIG_APP_SECURE_VERSION
|
||||
.secure_version = CONFIG_APP_SECURE_VERSION,
|
||||
#else
|
||||
.secure_version = 0,
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_APP_COMPILE_TIME_DATE
|
||||
.time = __TIME__,
|
||||
.date = __DATE__,
|
||||
#else
|
||||
.time = "",
|
||||
.date = "",
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
#ifndef CONFIG_APP_EXCLUDE_PROJECT_VER_VAR
|
||||
_Static_assert(sizeof(PROJECT_VER) <= sizeof(esp_app_desc.version), "PROJECT_VER is longer than version field in structure");
|
||||
#endif
|
||||
_Static_assert(sizeof(IDF_VER) <= sizeof(esp_app_desc.idf_ver), "IDF_VER is longer than idf_ver field in structure");
|
||||
#ifndef CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR
|
||||
_Static_assert(sizeof(PROJECT_NAME) <= sizeof(esp_app_desc.project_name), "PROJECT_NAME is longer than project_name field in structure");
|
||||
#endif
|
||||
|
||||
const esp_app_desc_t *esp_ota_get_app_description(void)
|
||||
{
|
||||
return &esp_app_desc;
|
||||
}
|
||||
|
||||
/* The following two functions may be called from the panic handler
|
||||
* or core dump, hence IRAM_ATTR.
|
||||
*/
|
||||
|
||||
static inline char IRAM_ATTR to_hex_digit(unsigned val)
|
||||
{
|
||||
return (val < 10) ? ('0' + val) : ('a' + val - 10);
|
||||
}
|
||||
|
||||
__attribute__((constructor)) void esp_ota_init_app_elf_sha256(void)
|
||||
{
|
||||
esp_ota_get_app_elf_sha256(NULL, 0);
|
||||
}
|
||||
|
||||
/* The esp_app_desc.app_elf_sha256 should be possible to print in panic handler during cache is disabled.
|
||||
* But because the cache is disabled the reading esp_app_desc.app_elf_sha256 is not right and
|
||||
* can lead to a complete lock-up of the CPU.
|
||||
* For this reason we do a reading of esp_app_desc.app_elf_sha256 while start up in esp_ota_init_app_elf_sha256()
|
||||
* and keep it in the static s_app_elf_sha256 value.
|
||||
*/
|
||||
int IRAM_ATTR esp_ota_get_app_elf_sha256(char* dst, size_t size)
|
||||
{
|
||||
static char s_app_elf_sha256[CONFIG_APP_RETRIEVE_LEN_ELF_SHA / 2];
|
||||
static bool first_call = true;
|
||||
if (first_call) {
|
||||
first_call = false;
|
||||
const uint8_t* src = esp_app_desc.app_elf_sha256;
|
||||
for (size_t i = 0; i < sizeof(s_app_elf_sha256); ++i) {
|
||||
s_app_elf_sha256[i] = src[i];
|
||||
}
|
||||
}
|
||||
if (dst == NULL || size == 0) {
|
||||
return 0;
|
||||
}
|
||||
size_t n = MIN((size - 1) / 2, sizeof(s_app_elf_sha256));
|
||||
for (size_t i = 0; i < n; ++i) {
|
||||
dst[2*i] = to_hex_digit(s_app_elf_sha256[i] >> 4);
|
||||
dst[2*i + 1] = to_hex_digit(s_app_elf_sha256[i] & 0xf);
|
||||
}
|
||||
dst[2*n] = 0;
|
||||
return 2*n + 1;
|
||||
}
|
||||
@@ -36,14 +36,11 @@
|
||||
#include "rom/crc.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_flash_data_types.h"
|
||||
#include "bootloader_common.h"
|
||||
#include "sys/param.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_efuse.h"
|
||||
|
||||
|
||||
#define SUB_TYPE_ID(i) (i & 0x0F)
|
||||
#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;
|
||||
@@ -55,10 +52,19 @@ typedef struct ota_ops_entry_ {
|
||||
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";
|
||||
|
||||
@@ -71,63 +77,6 @@ static bool is_ota_partition(const esp_partition_t *p)
|
||||
&& p->subtype < ESP_PARTITION_SUBTYPE_APP_OTA_MAX);
|
||||
}
|
||||
|
||||
// Read otadata partition and fill array from two otadata structures.
|
||||
// Also return pointer to otadata info partition.
|
||||
static const esp_partition_t *read_otadata(esp_ota_select_entry_t *two_otadata)
|
||||
{
|
||||
const esp_partition_t *otadata_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
|
||||
if (otadata_partition == NULL) {
|
||||
ESP_LOGE(TAG, "not found otadata");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
spi_flash_mmap_handle_t ota_data_map;
|
||||
const void *result = NULL;
|
||||
esp_err_t err = esp_partition_mmap(otadata_partition, 0, otadata_partition->size, SPI_FLASH_MMAP_DATA, &result, &ota_data_map);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "mmap otadata filed. Err=0x%8x", err);
|
||||
return NULL;
|
||||
} else {
|
||||
memcpy(&two_otadata[0], result, sizeof(esp_ota_select_entry_t));
|
||||
memcpy(&two_otadata[1], result + SPI_FLASH_SEC_SIZE, sizeof(esp_ota_select_entry_t));
|
||||
spi_flash_munmap(ota_data_map);
|
||||
}
|
||||
return otadata_partition;
|
||||
}
|
||||
|
||||
static esp_err_t image_validate(const esp_partition_t *partition, esp_image_load_mode_t load_mode)
|
||||
{
|
||||
esp_image_metadata_t data;
|
||||
const esp_partition_pos_t part_pos = {
|
||||
.offset = partition->address,
|
||||
.size = partition->size,
|
||||
};
|
||||
|
||||
if (esp_image_verify(load_mode, &part_pos, &data) != ESP_OK) {
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECURE_SIGNED_ON_UPDATE
|
||||
esp_err_t ret = esp_secure_boot_verify_signature(partition->address, data.image_len);
|
||||
if (ret != ESP_OK) {
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_ota_img_states_t set_new_state_otadata(void)
|
||||
{
|
||||
#ifdef CONFIG_APP_ROLLBACK_ENABLE
|
||||
ESP_LOGD(TAG, "Monitoring the first boot of the app is enabled.");
|
||||
return ESP_OTA_IMG_NEW;
|
||||
#else
|
||||
return ESP_OTA_IMG_UNDEFINED;
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_begin(const esp_partition_t *partition, size_t image_size, esp_ota_handle_t *out_handle)
|
||||
{
|
||||
ota_ops_entry_t *new_entry;
|
||||
@@ -146,27 +95,15 @@ esp_err_t esp_ota_begin(const esp_partition_t *partition, size_t image_size, esp
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const esp_partition_t* running_partition = esp_ota_get_running_partition();
|
||||
if (partition == running_partition) {
|
||||
if (partition == esp_ota_get_running_partition()) {
|
||||
return ESP_ERR_OTA_PARTITION_CONFLICT;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_APP_ROLLBACK_ENABLE
|
||||
esp_ota_img_states_t ota_state_running_part;
|
||||
if (esp_ota_get_state_partition(running_partition, &ota_state_running_part) == ESP_OK) {
|
||||
if (ota_state_running_part == ESP_OTA_IMG_PENDING_VERIFY) {
|
||||
ESP_LOGE(TAG, "Running app has not confirmed state (ESP_OTA_IMG_PENDING_VERIFY)");
|
||||
return ESP_ERR_OTA_ROLLBACK_INVALID_STATE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// If input image size is 0 or OTA_SIZE_UNKNOWN, erase entire partition
|
||||
if ((image_size == 0) || (image_size == OTA_SIZE_UNKNOWN)) {
|
||||
ret = esp_partition_erase_range(partition, 0, partition->size);
|
||||
} else {
|
||||
const int aligned_erase_size = (image_size + SPI_FLASH_SEC_SIZE - 1) & ~(SPI_FLASH_SEC_SIZE - 1);
|
||||
ret = esp_partition_erase_range(partition, 0, aligned_erase_size);
|
||||
ret = esp_partition_erase_range(partition, 0, (image_size / SPI_FLASH_SEC_SIZE + 1) * SPI_FLASH_SEC_SIZE);
|
||||
}
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
@@ -209,7 +146,7 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size)
|
||||
// must erase the partition before writing to it
|
||||
assert(it->erased_size > 0 && "must erase the partition before writing to it");
|
||||
if (it->wrote_size == 0 && it->partial_bytes == 0 && size > 0 && data_bytes[0] != ESP_IMAGE_HEADER_MAGIC) {
|
||||
ESP_LOGE(TAG, "OTA image has invalid magic byte (expected 0xE9, saw 0x%02x)", data_bytes[0]);
|
||||
ESP_LOGE(TAG, "OTA image has invalid magic byte (expected 0xE9, saw 0x%02x", data_bytes[0]);
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
|
||||
@@ -219,7 +156,7 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size)
|
||||
|
||||
/* check if we have partially written data from earlier */
|
||||
if (it->partial_bytes != 0) {
|
||||
copy_len = MIN(16 - it->partial_bytes, size);
|
||||
copy_len = OTA_MIN(16 - it->partial_bytes, size);
|
||||
memcpy(it->partial_data + it->partial_bytes, data_bytes, copy_len);
|
||||
it->partial_bytes += copy_len;
|
||||
if (it->partial_bytes != 16) {
|
||||
@@ -309,19 +246,31 @@ esp_err_t esp_ota_end(esp_ota_handle_t handle)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static esp_err_t rewrite_ota_seq(esp_ota_select_entry_t *two_otadata, uint32_t seq, uint8_t sec_id, const esp_partition_t *ota_data_partition)
|
||||
static uint32_t ota_select_crc(const ota_select *s)
|
||||
{
|
||||
if (two_otadata == NULL || sec_id > 1) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return crc32_le(UINT32_MAX, (uint8_t *)&s->ota_seq, 4);
|
||||
}
|
||||
|
||||
two_otadata[sec_id].ota_seq = seq;
|
||||
two_otadata[sec_id].crc = bootloader_common_ota_select_crc(&two_otadata[sec_id]);
|
||||
esp_err_t ret = esp_partition_erase_range(ota_data_partition, sec_id * SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE);
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
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_partition_write(ota_data_partition, SPI_FLASH_SEC_SIZE * sec_id, &two_otadata[sec_id], sizeof(esp_ota_select_entry_t));
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,88 +286,119 @@ static uint8_t get_ota_partition_count(void)
|
||||
|
||||
static esp_err_t esp_rewrite_ota_data(esp_partition_subtype_t subtype)
|
||||
{
|
||||
esp_ota_select_entry_t otadata[2];
|
||||
const esp_partition_t *otadata_partition = read_otadata(otadata);
|
||||
if (otadata_partition == NULL) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
esp_err_t ret;
|
||||
const esp_partition_t *find_partition = NULL;
|
||||
uint16_t ota_app_count = 0;
|
||||
uint32_t i = 0;
|
||||
uint32_t seq;
|
||||
spi_flash_mmap_handle_t ota_data_map;
|
||||
const void *result = NULL;
|
||||
|
||||
int ota_app_count = get_ota_partition_count();
|
||||
if (SUB_TYPE_ID(subtype) >= ota_app_count) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
//esp32_idf use two sector for store information about which partition is running
|
||||
//it defined the two sector as ota data partition,two structure esp_ota_select_entry_t is saved in the two sector
|
||||
//named data in first sector as otadata[0], second sector data as otadata[1]
|
||||
//e.g.
|
||||
//if otadata[0].ota_seq == otadata[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 otadata[0].ota_seq != 0 and otadata[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 otadata[0].ota_seq = 4, otadata[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 otadata[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
|
||||
|
||||
int active_otadata = bootloader_common_get_active_otadata(otadata);
|
||||
if (active_otadata != -1) {
|
||||
uint32_t seq = otadata[active_otadata].ota_seq;
|
||||
uint32_t i = 0;
|
||||
while (seq > (SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count) {
|
||||
i++;
|
||||
find_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
if (find_partition != NULL) {
|
||||
ota_app_count = get_ota_partition_count();
|
||||
//esp32_idf use two sector for store information about which partition is running
|
||||
//it defined the two sector as ota data partition,two structure ota_select is saved in the two sector
|
||||
//named data in first sector as s_ota_select[0], second sector data as s_ota_select[1]
|
||||
//e.g.
|
||||
//if s_ota_select[0].ota_seq == s_ota_select[1].ota_seq == 0xFFFFFFFF,means ota info partition is in init status
|
||||
//so it will boot factory application(if there is),if there's no factory application,it will boot ota[0] application
|
||||
//if s_ota_select[0].ota_seq != 0 and s_ota_select[1].ota_seq != 0,it will choose a max seq ,and get value of max_seq%max_ota_app_number
|
||||
//and boot a subtype (mask 0x0F) value is (max_seq - 1)%max_ota_app_number,so if want switch to run ota[x],can use next formulas.
|
||||
//for example, if s_ota_select[0].ota_seq = 4, s_ota_select[1].ota_seq = 5, and there are 8 ota application,
|
||||
//current running is (5-1)%8 = 4,running ota[4],so if we want to switch to run ota[7],
|
||||
//we should add s_ota_select[0].ota_seq (is 4) to 4 ,(8-1)%8=7,then it will boot ota[7]
|
||||
//if A=(B - C)%D
|
||||
//then B=(A + C)%D + D*n ,n= (0,1,2...)
|
||||
//so current ota app sub type id is x , dest bin subtype is y,total ota app count is n
|
||||
//seq will add (x + n*1 + 1 - seq)%n
|
||||
if (SUB_TYPE_ID(subtype) >= ota_app_count) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
int next_otadata = (~active_otadata)&1; // if 0 -> will be next 1. and if 1 -> will be next 0.
|
||||
otadata[next_otadata].ota_state = set_new_state_otadata();
|
||||
return rewrite_ota_seq(otadata, (SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, next_otadata, otadata_partition);
|
||||
|
||||
ret = esp_partition_mmap(find_partition, 0, find_partition->size, SPI_FLASH_MMAP_DATA, &result, &ota_data_map);
|
||||
if (ret != ESP_OK) {
|
||||
result = NULL;
|
||||
return ret;
|
||||
} else {
|
||||
memcpy(&s_ota_select[0], result, sizeof(ota_select));
|
||||
memcpy(&s_ota_select[1], result + SPI_FLASH_SEC_SIZE, sizeof(ota_select));
|
||||
spi_flash_munmap(ota_data_map);
|
||||
}
|
||||
|
||||
if (ota_select_valid(&s_ota_select[0]) && ota_select_valid(&s_ota_select[1])) {
|
||||
seq = OTA_MAX(s_ota_select[0].ota_seq, s_ota_select[1].ota_seq);
|
||||
while (seq > (SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count) {
|
||||
i++;
|
||||
}
|
||||
|
||||
if (s_ota_select[0].ota_seq >= s_ota_select[1].ota_seq) {
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 1, find_partition);
|
||||
} else {
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 0, find_partition);
|
||||
}
|
||||
|
||||
} else if (ota_select_valid(&s_ota_select[0])) {
|
||||
while (s_ota_select[0].ota_seq > (SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count) {
|
||||
i++;
|
||||
}
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 1, find_partition);
|
||||
|
||||
} else if (ota_select_valid(&s_ota_select[1])) {
|
||||
while (s_ota_select[1].ota_seq > (SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count) {
|
||||
i++;
|
||||
}
|
||||
return rewrite_ota_seq((SUB_TYPE_ID(subtype) + 1) % ota_app_count + i * ota_app_count, 0, find_partition);
|
||||
|
||||
} else {
|
||||
/* Both OTA slots are invalid, probably because unformatted... */
|
||||
return rewrite_ota_seq(SUB_TYPE_ID(subtype) + 1, 0, find_partition);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Both OTA slots are invalid, probably because unformatted... */
|
||||
int next_otadata = 0;
|
||||
otadata[next_otadata].ota_state = set_new_state_otadata();
|
||||
return rewrite_ota_seq(otadata, SUB_TYPE_ID(subtype) + 1, next_otadata, otadata_partition);
|
||||
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;
|
||||
if (partition == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (image_validate(partition, ESP_IMAGE_VERIFY) != ESP_OK) {
|
||||
esp_image_metadata_t data;
|
||||
const esp_partition_pos_t part_pos = {
|
||||
.offset = partition->address,
|
||||
.size = partition->size,
|
||||
};
|
||||
if (esp_image_verify(ESP_IMAGE_VERIFY, &part_pos, &data) != ESP_OK) {
|
||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECURE_SIGNED_ON_UPDATE
|
||||
esp_err_t ret = esp_secure_boot_verify_signature(partition->address, data.image_len);
|
||||
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) {
|
||||
const esp_partition_t *find_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
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 {
|
||||
#ifdef CONFIG_APP_ANTI_ROLLBACK
|
||||
esp_app_desc_t partition_app_desc;
|
||||
esp_err_t err = esp_ota_get_partition_description(partition, &partition_app_desc);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
// 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;
|
||||
}
|
||||
|
||||
if (esp_efuse_check_secure_version(partition_app_desc.secure_version) == false) {
|
||||
ESP_LOGE(TAG, "This a new partition can not be booted due to a secure version is lower than stored in efuse. Partition will be erased.");
|
||||
esp_err_t err = esp_partition_erase_range(partition, 0, partition->size);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
return ESP_ERR_OTA_SMALL_SEC_VER;
|
||||
}
|
||||
#endif
|
||||
return esp_rewrite_ota_data(partition->subtype);
|
||||
}
|
||||
} else {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
@@ -455,30 +435,58 @@ static const esp_partition_t *find_default_boot_partition(void)
|
||||
|
||||
const esp_partition_t *esp_ota_get_boot_partition(void)
|
||||
{
|
||||
esp_ota_select_entry_t otadata[2];
|
||||
const esp_partition_t *otadata_partition = read_otadata(otadata);
|
||||
if (otadata_partition == NULL) {
|
||||
esp_err_t ret;
|
||||
const esp_partition_t *find_partition = NULL;
|
||||
spi_flash_mmap_handle_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;
|
||||
}
|
||||
|
||||
int ota_app_count = get_ota_partition_count();
|
||||
ret = esp_partition_mmap(find_partition, 0, find_partition->size, SPI_FLASH_MMAP_DATA, &result, &ota_data_map);
|
||||
if (ret != ESP_OK) {
|
||||
spi_flash_munmap(ota_data_map);
|
||||
ESP_LOGE(TAG, "mmap ota data filed");
|
||||
return NULL;
|
||||
} else {
|
||||
memcpy(&s_ota_select[0], result, sizeof(ota_select));
|
||||
memcpy(&s_ota_select[1], result + 0x1000, sizeof(ota_select));
|
||||
spi_flash_munmap(ota_data_map);
|
||||
}
|
||||
ota_app_count = get_ota_partition_count();
|
||||
|
||||
ESP_LOGD(TAG, "found ota app max = %d", ota_app_count);
|
||||
|
||||
if ((bootloader_common_ota_select_invalid(&otadata[0]) &&
|
||||
bootloader_common_ota_select_invalid(&otadata[1])) ||
|
||||
ota_app_count == 0) {
|
||||
ESP_LOGD(TAG, "finding factory app...");
|
||||
if (s_ota_select[0].ota_seq == 0xFFFFFFFF && s_ota_select[1].ota_seq == 0xFFFFFFFF) {
|
||||
ESP_LOGD(TAG, "finding factory app......");
|
||||
return find_default_boot_partition();
|
||||
} else if (ota_select_valid(&s_ota_select[0]) && ota_select_valid(&s_ota_select[1])) {
|
||||
ESP_LOGD(TAG, "finding ota_%d app......", \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ((OTA_MAX(s_ota_select[0].ota_seq, s_ota_select[1].ota_seq) - 1) % ota_app_count));
|
||||
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ((OTA_MAX(s_ota_select[0].ota_seq, s_ota_select[1].ota_seq) - 1) % ota_app_count), NULL);
|
||||
} else if (ota_select_valid(&s_ota_select[0])) {
|
||||
ESP_LOGD(TAG, "finding ota_%d app......", \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[0].ota_seq - 1) % ota_app_count);
|
||||
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[0].ota_seq - 1) % ota_app_count, NULL);
|
||||
|
||||
} else if (ota_select_valid(&s_ota_select[1])) {
|
||||
ESP_LOGD(TAG, "finding ota_%d app......", \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[1].ota_seq - 1) % ota_app_count);
|
||||
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, \
|
||||
ESP_PARTITION_SUBTYPE_APP_OTA_MIN + (s_ota_select[1].ota_seq - 1) % ota_app_count, NULL);
|
||||
|
||||
} else {
|
||||
int active_otadata = bootloader_common_get_active_otadata(otadata);
|
||||
if (active_otadata != -1) {
|
||||
int ota_slot = (otadata[active_otadata].ota_seq - 1) % ota_app_count; // Actual OTA partition selection
|
||||
ESP_LOGD(TAG, "finding ota_%d app...", ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ota_slot);
|
||||
return esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ota_slot, NULL);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "ota data invalid, no current app. Assuming factory");
|
||||
return find_default_boot_partition();
|
||||
}
|
||||
ESP_LOGE(TAG, "ota data invalid, no current app. Assuming factory");
|
||||
return find_default_boot_partition();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -567,265 +575,3 @@ const esp_partition_t* esp_ota_get_next_update_partition(const esp_partition_t *
|
||||
return default_ota;
|
||||
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_get_partition_description(const esp_partition_t *partition, esp_app_desc_t *app_desc)
|
||||
{
|
||||
if (partition == NULL || app_desc == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if(partition->type != ESP_PARTITION_TYPE_APP) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
esp_err_t err = esp_partition_read(partition, sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t), app_desc, sizeof(esp_app_desc_t));
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (app_desc->magic_word != ESP_APP_DESC_MAGIC_WORD) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_APP_ANTI_ROLLBACK
|
||||
static esp_err_t esp_ota_set_anti_rollback(void) {
|
||||
const esp_app_desc_t *app_desc = esp_ota_get_app_description();
|
||||
return esp_efuse_update_secure_version(app_desc->secure_version);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Checks applications on the slots which can be booted in case of rollback.
|
||||
// Returns true if the slots have at least one app (except the running app).
|
||||
bool esp_ota_check_rollback_is_possible(void)
|
||||
{
|
||||
esp_ota_select_entry_t otadata[2];
|
||||
if (read_otadata(otadata) == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int ota_app_count = get_ota_partition_count();
|
||||
if (ota_app_count == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool valid_otadata[2];
|
||||
valid_otadata[0] = bootloader_common_ota_select_valid(&otadata[0]);
|
||||
valid_otadata[1] = bootloader_common_ota_select_valid(&otadata[1]);
|
||||
|
||||
int active_ota = bootloader_common_select_otadata(otadata, valid_otadata, true);
|
||||
if (active_ota == -1) {
|
||||
return false;
|
||||
}
|
||||
int last_active_ota = (~active_ota)&1;
|
||||
|
||||
const esp_partition_t *partition = NULL;
|
||||
#ifndef CONFIG_APP_ANTI_ROLLBACK
|
||||
if (valid_otadata[last_active_ota] == false) {
|
||||
partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_FACTORY, NULL);
|
||||
if (partition != NULL) {
|
||||
if(image_validate(partition, ESP_IMAGE_VERIFY_SILENT) == ESP_OK) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (valid_otadata[last_active_ota] == true) {
|
||||
int slot = (otadata[last_active_ota].ota_seq - 1) % ota_app_count;
|
||||
partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_MIN + slot, NULL);
|
||||
if (partition != NULL) {
|
||||
if(image_validate(partition, ESP_IMAGE_VERIFY_SILENT) == ESP_OK) {
|
||||
#ifdef CONFIG_APP_ANTI_ROLLBACK
|
||||
esp_app_desc_t app_desc;
|
||||
if (esp_ota_get_partition_description(partition, &app_desc) == ESP_OK &&
|
||||
esp_efuse_check_secure_version(app_desc.secure_version) == true) {
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// if valid == false - will done rollback with reboot. After reboot will boot previous OTA[x] or Factory partition.
|
||||
// if valid == true - it confirm that current OTA[x] is workable. Reboot will not happen.
|
||||
static esp_err_t esp_ota_current_ota_is_workable(bool valid)
|
||||
{
|
||||
esp_ota_select_entry_t otadata[2];
|
||||
const esp_partition_t *otadata_partition = read_otadata(otadata);
|
||||
if (otadata_partition == NULL) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
int active_otadata = bootloader_common_get_active_otadata(otadata);
|
||||
if (active_otadata != -1 && get_ota_partition_count() != 0) {
|
||||
if (valid == true && otadata[active_otadata].ota_state != ESP_OTA_IMG_VALID) {
|
||||
otadata[active_otadata].ota_state = ESP_OTA_IMG_VALID;
|
||||
ESP_LOGD(TAG, "OTA[current] partition is marked as VALID");
|
||||
esp_err_t err = rewrite_ota_seq(otadata, otadata[active_otadata].ota_seq, active_otadata, otadata_partition);
|
||||
#ifdef CONFIG_APP_ANTI_ROLLBACK
|
||||
if (err == ESP_OK) {
|
||||
return esp_ota_set_anti_rollback();
|
||||
}
|
||||
#endif
|
||||
return err;
|
||||
} else if (valid == false) {
|
||||
if (esp_ota_check_rollback_is_possible() == false) {
|
||||
ESP_LOGE(TAG, "Rollback is not possible, do not have any suitable apps in slots");
|
||||
return ESP_ERR_OTA_ROLLBACK_FAILED;
|
||||
}
|
||||
ESP_LOGD(TAG, "OTA[current] partition is marked as INVALID");
|
||||
otadata[active_otadata].ota_state = ESP_OTA_IMG_INVALID;
|
||||
esp_err_t err = rewrite_ota_seq(otadata, otadata[active_otadata].ota_seq, active_otadata, otadata_partition);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
ESP_LOGI(TAG, "Rollback to previously worked partition. Restart.");
|
||||
esp_restart();
|
||||
}
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Running firmware is factory");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_mark_app_valid_cancel_rollback()
|
||||
{
|
||||
return esp_ota_current_ota_is_workable(true);
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_mark_app_invalid_rollback_and_reboot()
|
||||
{
|
||||
return esp_ota_current_ota_is_workable(false);
|
||||
}
|
||||
|
||||
static bool check_invalid_otadata (const esp_ota_select_entry_t *s) {
|
||||
return s->ota_seq != UINT32_MAX &&
|
||||
s->crc == bootloader_common_ota_select_crc(s) &&
|
||||
(s->ota_state == ESP_OTA_IMG_INVALID ||
|
||||
s->ota_state == ESP_OTA_IMG_ABORTED);
|
||||
}
|
||||
|
||||
static int get_last_invalid_otadata(const esp_ota_select_entry_t *two_otadata)
|
||||
{
|
||||
|
||||
bool invalid_otadata[2];
|
||||
invalid_otadata[0] = check_invalid_otadata(&two_otadata[0]);
|
||||
invalid_otadata[1] = check_invalid_otadata(&two_otadata[1]);
|
||||
int num_invalid_otadata = bootloader_common_select_otadata(two_otadata, invalid_otadata, false);
|
||||
ESP_LOGD(TAG, "Invalid otadata[%d]", num_invalid_otadata);
|
||||
return num_invalid_otadata;
|
||||
}
|
||||
|
||||
const esp_partition_t* esp_ota_get_last_invalid_partition()
|
||||
{
|
||||
esp_ota_select_entry_t otadata[2];
|
||||
if (read_otadata(otadata) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int invalid_otadata = get_last_invalid_otadata(otadata);
|
||||
|
||||
int ota_app_count = get_ota_partition_count();
|
||||
if (invalid_otadata != -1 && ota_app_count != 0) {
|
||||
int ota_slot = (otadata[invalid_otadata].ota_seq - 1) % ota_app_count;
|
||||
ESP_LOGD(TAG, "Find invalid ota_%d app", ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ota_slot);
|
||||
|
||||
const esp_partition_t* invalid_partition = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ota_slot, NULL);
|
||||
if (invalid_partition != NULL) {
|
||||
if (image_validate(invalid_partition, ESP_IMAGE_VERIFY_SILENT) != ESP_OK) {
|
||||
ESP_LOGD(TAG, "Last invalid partition has corrupted app");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return invalid_partition;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_get_state_partition(const esp_partition_t *partition, esp_ota_img_states_t *ota_state)
|
||||
{
|
||||
if (partition == NULL || ota_state == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (!is_ota_partition(partition)) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
esp_ota_select_entry_t otadata[2];
|
||||
int ota_app_count = get_ota_partition_count();
|
||||
if (read_otadata(otadata) == NULL || ota_app_count == 0) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
int req_ota_slot = partition->subtype - ESP_PARTITION_SUBTYPE_APP_OTA_MIN;
|
||||
bool not_found = true;
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
int ota_slot = (otadata[i].ota_seq - 1) % ota_app_count;
|
||||
if (ota_slot == req_ota_slot && otadata[i].crc == bootloader_common_ota_select_crc(&otadata[i])) {
|
||||
*ota_state = otadata[i].ota_state;
|
||||
not_found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (not_found) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_ota_erase_last_boot_app_partition(void)
|
||||
{
|
||||
esp_ota_select_entry_t otadata[2];
|
||||
const esp_partition_t* ota_data_partition = read_otadata(otadata);
|
||||
if (ota_data_partition == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
int active_otadata = bootloader_common_get_active_otadata(otadata);
|
||||
int ota_app_count = get_ota_partition_count();
|
||||
if (active_otadata == -1 || ota_app_count == 0) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
int inactive_otadata = (~active_otadata)&1;
|
||||
if (otadata[inactive_otadata].ota_seq == UINT32_MAX || otadata[inactive_otadata].crc != bootloader_common_ota_select_crc(&otadata[inactive_otadata])) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
int ota_slot = (otadata[inactive_otadata].ota_seq - 1) % ota_app_count; // Actual OTA partition selection
|
||||
ESP_LOGD(TAG, "finding last_boot_app_partition ota_%d app...", ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ota_slot);
|
||||
|
||||
const esp_partition_t* last_boot_app_partition_from_otadata = esp_partition_find_first(ESP_PARTITION_TYPE_APP, ESP_PARTITION_SUBTYPE_APP_OTA_MIN + ota_slot, NULL);
|
||||
if (last_boot_app_partition_from_otadata == NULL) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
const esp_partition_t* running_partition = esp_ota_get_running_partition();
|
||||
if (running_partition == NULL || last_boot_app_partition_from_otadata == running_partition) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
esp_err_t err = esp_partition_erase_range(last_boot_app_partition_from_otadata, 0, last_boot_app_partition_from_otadata->size);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
int sec_id = inactive_otadata;
|
||||
err = esp_partition_erase_range(ota_data_partition, sec_id * SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
82
components/app_update/gen_empty_partition.py
Executable file
82
components/app_update/gen_empty_partition.py
Executable file
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# generates an empty binary file
|
||||
#
|
||||
# This tool generates an empty binary file of the required size.
|
||||
#
|
||||
# Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http:#www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from __future__ import print_function, division
|
||||
from __future__ import unicode_literals
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import struct
|
||||
import sys
|
||||
import hashlib
|
||||
import binascii
|
||||
|
||||
__version__ = '1.0'
|
||||
|
||||
quiet = False
|
||||
|
||||
def status(msg):
|
||||
""" Print status message to stderr """
|
||||
if not quiet:
|
||||
critical(msg)
|
||||
|
||||
def critical(msg):
|
||||
""" Print critical message to stderr """
|
||||
if not quiet:
|
||||
sys.stderr.write(msg)
|
||||
sys.stderr.write('\n')
|
||||
|
||||
def generate_blanked_file(size, output_path):
|
||||
output = b"\xFF" * size
|
||||
try:
|
||||
stdout_binary = sys.stdout.buffer # Python 3
|
||||
except AttributeError:
|
||||
stdout_binary = sys.stdout
|
||||
with stdout_binary if output_path == '-' else open(output_path, 'wb') as f:
|
||||
f.write(output)
|
||||
|
||||
def main():
|
||||
global quiet
|
||||
parser = argparse.ArgumentParser(description='Generates an empty binary file of the required size.')
|
||||
|
||||
parser.add_argument('--quiet', '-q', help="Don't print status messages to stderr", action='store_true')
|
||||
|
||||
parser.add_argument('--size', help='Size of generated the file', type=str, required=True)
|
||||
|
||||
parser.add_argument('output', help='Path for binary file.', nargs='?', default='-')
|
||||
args = parser.parse_args()
|
||||
|
||||
quiet = args.quiet
|
||||
|
||||
size = int(args.size, 0)
|
||||
if size > 0 :
|
||||
generate_blanked_file(size, args.output)
|
||||
return 0
|
||||
|
||||
class InputError(RuntimeError):
|
||||
def __init__(self, e):
|
||||
super(InputError, self).__init__(e)
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
r = main()
|
||||
sys.exit(r)
|
||||
except InputError as e:
|
||||
print(e, file=sys.stderr)
|
||||
sys.exit(2)
|
||||
@@ -20,8 +20,6 @@
|
||||
#include <stddef.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_partition.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_flash_data_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
@@ -34,10 +32,6 @@ extern "C"
|
||||
#define ESP_ERR_OTA_PARTITION_CONFLICT (ESP_ERR_OTA_BASE + 0x01) /*!< Error if request was to write or erase the current running partition */
|
||||
#define ESP_ERR_OTA_SELECT_INFO_INVALID (ESP_ERR_OTA_BASE + 0x02) /*!< Error if OTA data partition contains invalid content */
|
||||
#define ESP_ERR_OTA_VALIDATE_FAILED (ESP_ERR_OTA_BASE + 0x03) /*!< Error if OTA app image is invalid */
|
||||
#define ESP_ERR_OTA_SMALL_SEC_VER (ESP_ERR_OTA_BASE + 0x04) /*!< Error if the firmware has a secure version less than the running firmware. */
|
||||
#define ESP_ERR_OTA_ROLLBACK_FAILED (ESP_ERR_OTA_BASE + 0x05) /*!< Error if flash does not have valid firmware in passive partition and hence rollback is not possible */
|
||||
#define ESP_ERR_OTA_ROLLBACK_INVALID_STATE (ESP_ERR_OTA_BASE + 0x06) /*!< Error if current active firmware is still marked in pending validation state (ESP_OTA_IMG_PENDING_VERIFY), essentially first boot of firmware image post upgrade and hence firmware upgrade is not possible */
|
||||
|
||||
|
||||
/**
|
||||
* @brief Opaque handle for an application OTA update
|
||||
@@ -47,24 +41,6 @@ extern "C"
|
||||
*/
|
||||
typedef uint32_t esp_ota_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Return esp_app_desc structure. This structure includes app version.
|
||||
*
|
||||
* Return description for running app.
|
||||
* @return Pointer to esp_app_desc structure.
|
||||
*/
|
||||
const esp_app_desc_t *esp_ota_get_app_description(void);
|
||||
|
||||
/**
|
||||
* @brief Fill the provided buffer with SHA256 of the ELF file, formatted as hexadecimal, null-terminated.
|
||||
* If the buffer size is not sufficient to fit the entire SHA256 in hex plus a null terminator,
|
||||
* the largest possible number of bytes will be written followed by a null.
|
||||
* @param dst Destination buffer
|
||||
* @param size Size of the buffer
|
||||
* @return Number of bytes written to dst (including null terminator)
|
||||
*/
|
||||
int esp_ota_get_app_elf_sha256(char* dst, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Commence an OTA update writing to the specified partition.
|
||||
|
||||
@@ -76,10 +52,6 @@ int esp_ota_get_app_elf_sha256(char* dst, size_t size);
|
||||
* On success, this function allocates memory that remains in use
|
||||
* until esp_ota_end() is called with the returned handle.
|
||||
*
|
||||
* Note: If the rollback option is enabled and the running application has the ESP_OTA_IMG_PENDING_VERIFY state then
|
||||
* it will lead to the ESP_ERR_OTA_ROLLBACK_INVALID_STATE error. Confirm the running app before to run download a new app,
|
||||
* use esp_ota_mark_app_valid_cancel_rollback() function for it (this should be done as early as possible when you first download a new application).
|
||||
*
|
||||
* @param partition Pointer to info for partition which will receive the OTA update. Required.
|
||||
* @param image_size Size of new OTA app image. Partition will be erased in order to receive this size of image. If 0 or OTA_SIZE_UNKNOWN, the entire partition is erased.
|
||||
* @param out_handle On success, returns a handle which should be used for subsequent esp_ota_write() and esp_ota_end() calls.
|
||||
@@ -93,7 +65,6 @@ int esp_ota_get_app_elf_sha256(char* dst, size_t size);
|
||||
* - ESP_ERR_OTA_SELECT_INFO_INVALID: The OTA data partition contains invalid data.
|
||||
* - ESP_ERR_INVALID_SIZE: Partition doesn't fit in configured flash size.
|
||||
* - ESP_ERR_FLASH_OP_TIMEOUT or ESP_ERR_FLASH_OP_FAIL: Flash write failed.
|
||||
* - ESP_ERR_OTA_ROLLBACK_INVALID_STATE: If the running app has not confirmed state. Before performing an update, the application must be valid.
|
||||
*/
|
||||
esp_err_t esp_ota_begin(const esp_partition_t* partition, size_t image_size, esp_ota_handle_t* out_handle);
|
||||
|
||||
@@ -199,83 +170,6 @@ const esp_partition_t* esp_ota_get_running_partition(void);
|
||||
*/
|
||||
const esp_partition_t* esp_ota_get_next_update_partition(const esp_partition_t *start_from);
|
||||
|
||||
/**
|
||||
* @brief Returns esp_app_desc structure for app partition. This structure includes app version.
|
||||
*
|
||||
* Returns a description for the requested app partition.
|
||||
* @param[in] partition Pointer to app partition. (only app partition)
|
||||
* @param[out] app_desc Structure of info about app.
|
||||
* @return
|
||||
* - ESP_OK Successful.
|
||||
* - ESP_ERR_NOT_FOUND app_desc structure is not found. Magic word is incorrect.
|
||||
* - ESP_ERR_NOT_SUPPORTED Partition is not application.
|
||||
* - ESP_ERR_INVALID_ARG Arguments is NULL or if partition's offset exceeds partition size.
|
||||
* - ESP_ERR_INVALID_SIZE Read would go out of bounds of the partition.
|
||||
* - or one of error codes from lower-level flash driver.
|
||||
*/
|
||||
esp_err_t esp_ota_get_partition_description(const esp_partition_t *partition, esp_app_desc_t *app_desc);
|
||||
|
||||
/**
|
||||
* @brief This function is called to indicate that the running app is working well.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: if successful.
|
||||
*/
|
||||
esp_err_t esp_ota_mark_app_valid_cancel_rollback();
|
||||
|
||||
/**
|
||||
* @brief This function is called to roll back to the previously workable app with reboot.
|
||||
*
|
||||
* If rollback is successful then device will reset else API will return with error code.
|
||||
* Checks applications on a flash drive that can be booted in case of rollback.
|
||||
* If the flash does not have at least one app (except the running app) then rollback is not possible.
|
||||
* @return
|
||||
* - ESP_FAIL: if not successful.
|
||||
* - ESP_ERR_OTA_ROLLBACK_FAILED: The rollback is not possible due to flash does not have any apps.
|
||||
*/
|
||||
esp_err_t esp_ota_mark_app_invalid_rollback_and_reboot();
|
||||
|
||||
/**
|
||||
* @brief Returns last partition with invalid state (ESP_OTA_IMG_INVALID or ESP_OTA_IMG_ABORTED).
|
||||
*
|
||||
* @return partition.
|
||||
*/
|
||||
const esp_partition_t* esp_ota_get_last_invalid_partition();
|
||||
|
||||
/**
|
||||
* @brief Returns state for given partition.
|
||||
*
|
||||
* @param[in] partition Pointer to partition.
|
||||
* @param[out] ota_state state of partition (if this partition has a record in otadata).
|
||||
* @return
|
||||
* - ESP_OK: Successful.
|
||||
* - ESP_ERR_INVALID_ARG: partition or ota_state arguments were NULL.
|
||||
* - ESP_ERR_NOT_SUPPORTED: partition is not ota.
|
||||
* - ESP_ERR_NOT_FOUND: Partition table does not have otadata or state was not found for given partition.
|
||||
*/
|
||||
esp_err_t esp_ota_get_state_partition(const esp_partition_t *partition, esp_ota_img_states_t *ota_state);
|
||||
|
||||
/**
|
||||
* @brief Erase previous boot app partition and corresponding otadata select for this partition.
|
||||
*
|
||||
* When current app is marked to as valid then you can erase previous app partition.
|
||||
* @return
|
||||
* - ESP_OK: Successful, otherwise ESP_ERR.
|
||||
*/
|
||||
esp_err_t esp_ota_erase_last_boot_app_partition(void);
|
||||
|
||||
/**
|
||||
* @brief Checks applications on the slots which can be booted in case of rollback.
|
||||
*
|
||||
* These applications should be valid (marked in otadata as not UNDEFINED, INVALID or ABORTED and crc is good) and be able booted,
|
||||
* and secure_version of app >= secure_version of efuse (if anti-rollback is enabled).
|
||||
*
|
||||
* @return
|
||||
* - True: Returns true if the slots have at least one app (except the running app).
|
||||
* - False: The rollback is not possible.
|
||||
*/
|
||||
bool esp_ota_check_rollback_is_possible(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,339 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# otatool is used to perform ota-level operations - flashing ota partition
|
||||
# erasing ota partition and switching ota partition
|
||||
#
|
||||
# Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http:#www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from __future__ import print_function, division
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
import binascii
|
||||
import subprocess
|
||||
import tempfile
|
||||
import collections
|
||||
import struct
|
||||
|
||||
__version__ = '1.0'
|
||||
|
||||
IDF_COMPONENTS_PATH = os.path.expandvars(os.path.join("$IDF_PATH", "components"))
|
||||
|
||||
PARTTOOL_PY = os.path.join(IDF_COMPONENTS_PATH, "partition_table", "parttool.py")
|
||||
|
||||
SPI_FLASH_SEC_SIZE = 0x2000
|
||||
|
||||
quiet = False
|
||||
|
||||
|
||||
def status(msg):
|
||||
if not quiet:
|
||||
print(msg)
|
||||
|
||||
|
||||
def _invoke_parttool(parttool_args, args, output=False, partition=None):
|
||||
invoke_args = []
|
||||
|
||||
if partition:
|
||||
invoke_args += [sys.executable, PARTTOOL_PY] + partition
|
||||
else:
|
||||
invoke_args += [sys.executable, PARTTOOL_PY, "--partition-type", "data", "--partition-subtype", "ota"]
|
||||
|
||||
if quiet:
|
||||
invoke_args += ["-q"]
|
||||
|
||||
if args.port != "":
|
||||
invoke_args += ["--port", args.port]
|
||||
|
||||
if args.partition_table_file:
|
||||
invoke_args += ["--partition-table-file", args.partition_table_file]
|
||||
|
||||
if args.partition_table_offset:
|
||||
invoke_args += ["--partition-table-offset", args.partition_table_offset]
|
||||
|
||||
invoke_args += parttool_args
|
||||
|
||||
if output:
|
||||
return subprocess.check_output(invoke_args)
|
||||
else:
|
||||
return subprocess.check_call(invoke_args)
|
||||
|
||||
|
||||
def _get_otadata_contents(args, check=True):
|
||||
global quiet
|
||||
|
||||
if check:
|
||||
check_args = ["get_partition_info", "--info", "offset", "size"]
|
||||
|
||||
quiet = True
|
||||
output = _invoke_parttool(check_args, args, True).split(b" ")
|
||||
quiet = args.quiet
|
||||
|
||||
if not output:
|
||||
raise RuntimeError("No ota_data partition found")
|
||||
|
||||
with tempfile.NamedTemporaryFile(delete=False) as f:
|
||||
f_name = f.name
|
||||
|
||||
try:
|
||||
invoke_args = ["read_partition", "--output", f_name]
|
||||
_invoke_parttool(invoke_args, args)
|
||||
with open(f_name, "rb") as f:
|
||||
contents = f.read()
|
||||
finally:
|
||||
os.unlink(f_name)
|
||||
|
||||
return contents
|
||||
|
||||
|
||||
def _get_otadata_status(otadata_contents):
|
||||
status = []
|
||||
|
||||
otadata_status = collections.namedtuple("otadata_status", "seq crc")
|
||||
|
||||
for i in range(2):
|
||||
start = i * (SPI_FLASH_SEC_SIZE >> 1)
|
||||
|
||||
seq = bytearray(otadata_contents[start:start + 4])
|
||||
crc = bytearray(otadata_contents[start + 28:start + 32])
|
||||
|
||||
seq = struct.unpack('>I', seq)
|
||||
crc = struct.unpack('>I', crc)
|
||||
|
||||
status.append(otadata_status(seq[0], crc[0]))
|
||||
|
||||
return status
|
||||
|
||||
|
||||
def read_otadata(args):
|
||||
status("Reading ota_data partition contents...")
|
||||
otadata_info = _get_otadata_contents(args)
|
||||
otadata_info = _get_otadata_status(otadata_info)
|
||||
|
||||
print(otadata_info)
|
||||
|
||||
print("\t\t{:11}\t{:8s}|\t{:8s}\t{:8s}".format("OTA_SEQ", "CRC", "OTA_SEQ", "CRC"))
|
||||
print("Firmware: 0x{:8x} \t 0x{:8x} |\t0x{:8x} \t 0x{:8x}".format(otadata_info[0].seq, otadata_info[0].crc,
|
||||
otadata_info[1].seq, otadata_info[1].crc))
|
||||
|
||||
|
||||
def erase_otadata(args):
|
||||
status("Erasing ota_data partition contents...")
|
||||
_invoke_parttool(["erase_partition"], args)
|
||||
status("Erased ota_data partition contents")
|
||||
|
||||
|
||||
def switch_otadata(args):
|
||||
sys.path.append(os.path.join(IDF_COMPONENTS_PATH, "partition_table"))
|
||||
import gen_esp32part as gen
|
||||
|
||||
with tempfile.NamedTemporaryFile(delete=False) as f:
|
||||
f_name = f.name
|
||||
|
||||
try:
|
||||
def is_otadata_status_valid(status):
|
||||
seq = status.seq % (1 << 32)
|
||||
crc = hex(binascii.crc32(struct.pack("I", seq), 0xFFFFFFFF) % (1 << 32))
|
||||
return seq < (int('0xFFFFFFFF', 16) % (1 << 32)) and status.crc == crc
|
||||
|
||||
status("Looking for ota app partitions...")
|
||||
|
||||
# In order to get the number of ota app partitions, we need the partition table
|
||||
partition_table = None
|
||||
invoke_args = ["get_partition_info", "--table", f_name]
|
||||
|
||||
_invoke_parttool(invoke_args, args)
|
||||
|
||||
partition_table = open(f_name, "rb").read()
|
||||
partition_table = gen.PartitionTable.from_binary(partition_table)
|
||||
|
||||
ota_partitions = list()
|
||||
|
||||
for i in range(gen.NUM_PARTITION_SUBTYPE_APP_OTA):
|
||||
ota_partition = filter(lambda p: p.subtype == (gen.MIN_PARTITION_SUBTYPE_APP_OTA + i), partition_table)
|
||||
|
||||
try:
|
||||
ota_partitions.append(list(ota_partition)[0])
|
||||
except IndexError:
|
||||
break
|
||||
|
||||
ota_partitions = sorted(ota_partitions, key=lambda p: p.subtype)
|
||||
|
||||
if not ota_partitions:
|
||||
raise RuntimeError("No ota app partitions found")
|
||||
|
||||
status("Verifying partition to switch to exists...")
|
||||
|
||||
# Look for the app partition to switch to
|
||||
ota_partition_next = None
|
||||
|
||||
try:
|
||||
if args.name:
|
||||
ota_partition_next = filter(lambda p: p.name == args.name, ota_partitions)
|
||||
else:
|
||||
ota_partition_next = filter(lambda p: p.subtype - gen.MIN_PARTITION_SUBTYPE_APP_OTA == args.slot, ota_partitions)
|
||||
|
||||
ota_partition_next = list(ota_partition_next)[0]
|
||||
except IndexError:
|
||||
raise RuntimeError("Partition to switch to not found")
|
||||
|
||||
otadata_contents = _get_otadata_contents(args)
|
||||
otadata_status = _get_otadata_status(otadata_contents)
|
||||
|
||||
# Find the copy to base the computation for ota sequence number on
|
||||
otadata_compute_base = -1
|
||||
|
||||
# Both are valid, take the max as computation base
|
||||
if is_otadata_status_valid(otadata_status[0]) and is_otadata_status_valid(otadata_status[1]):
|
||||
if otadata_status[0].seq >= otadata_status[1].seq:
|
||||
otadata_compute_base = 0
|
||||
else:
|
||||
otadata_compute_base = 1
|
||||
# Only one copy is valid, use that
|
||||
elif is_otadata_status_valid(otadata_status[0]):
|
||||
otadata_compute_base = 0
|
||||
elif is_otadata_status_valid(otadata_status[1]):
|
||||
otadata_compute_base = 1
|
||||
# Both are invalid (could be initial state - all 0xFF's)
|
||||
else:
|
||||
pass
|
||||
|
||||
ota_seq_next = 0
|
||||
ota_partitions_num = len(ota_partitions)
|
||||
|
||||
target_seq = (ota_partition_next.subtype & 0x0F) + 1
|
||||
|
||||
# Find the next ota sequence number
|
||||
if otadata_compute_base == 0 or otadata_compute_base == 1:
|
||||
base_seq = otadata_status[otadata_compute_base].seq % (1 << 32)
|
||||
|
||||
i = 0
|
||||
while base_seq > target_seq % ota_partitions_num + i * ota_partitions_num:
|
||||
i += 1
|
||||
|
||||
ota_seq_next = target_seq % ota_partitions_num + i * ota_partitions_num
|
||||
else:
|
||||
ota_seq_next = target_seq
|
||||
|
||||
# Create binary data from computed values
|
||||
ota_seq_next = struct.pack("I", ota_seq_next)
|
||||
ota_seq_crc_next = binascii.crc32(ota_seq_next, 0xFFFFFFFF) % (1 << 32)
|
||||
ota_seq_crc_next = struct.pack("I", ota_seq_crc_next)
|
||||
|
||||
with open(f_name, "wb") as otadata_next_file:
|
||||
start = (1 if otadata_compute_base == 0 else 0) * (SPI_FLASH_SEC_SIZE >> 1)
|
||||
|
||||
otadata_next_file.write(otadata_contents)
|
||||
|
||||
otadata_next_file.seek(start)
|
||||
otadata_next_file.write(ota_seq_next)
|
||||
|
||||
otadata_next_file.seek(start + 28)
|
||||
otadata_next_file.write(ota_seq_crc_next)
|
||||
|
||||
otadata_next_file.flush()
|
||||
|
||||
_invoke_parttool(["write_partition", "--input", f_name], args)
|
||||
status("Updated ota_data partition")
|
||||
finally:
|
||||
os.unlink(f_name)
|
||||
|
||||
|
||||
def _get_partition_specifier(args):
|
||||
if args.name:
|
||||
return ["--partition-name", args.name]
|
||||
else:
|
||||
return ["--partition-type", "app", "--partition-subtype", "ota_" + str(args.slot)]
|
||||
|
||||
|
||||
def read_ota_partition(args):
|
||||
invoke_args = ["read_partition", "--output", args.output]
|
||||
_invoke_parttool(invoke_args, args, partition=_get_partition_specifier(args))
|
||||
status("Read ota partition contents to file {}".format(args.output))
|
||||
|
||||
|
||||
def write_ota_partition(args):
|
||||
invoke_args = ["write_partition", "--input", args.input]
|
||||
_invoke_parttool(invoke_args, args, partition=_get_partition_specifier(args))
|
||||
status("Written contents of file {} to ota partition".format(args.input))
|
||||
|
||||
|
||||
def erase_ota_partition(args):
|
||||
invoke_args = ["erase_partition"]
|
||||
_invoke_parttool(invoke_args, args, partition=_get_partition_specifier(args))
|
||||
status("Erased contents of ota partition")
|
||||
|
||||
|
||||
def main():
|
||||
global quiet
|
||||
|
||||
parser = argparse.ArgumentParser("ESP-IDF OTA Partitions Tool")
|
||||
|
||||
parser.add_argument("--quiet", "-q", help="suppress stderr messages", action="store_true")
|
||||
|
||||
# There are two possible sources for the partition table: a device attached to the host
|
||||
# or a partition table CSV/binary file. These sources are mutually exclusive.
|
||||
partition_table_info_source_args = parser.add_mutually_exclusive_group()
|
||||
|
||||
partition_table_info_source_args.add_argument("--port", "-p", help="port where the device to read the partition table from is attached", default="")
|
||||
partition_table_info_source_args.add_argument("--partition-table-file", "-f", help="file (CSV/binary) to read the partition table from", default="")
|
||||
|
||||
parser.add_argument("--partition-table-offset", "-o", help="offset to read the partition table from", default="0x8000")
|
||||
|
||||
subparsers = parser.add_subparsers(dest="operation", help="run otatool -h for additional help")
|
||||
|
||||
# Specify the supported operations
|
||||
subparsers.add_parser("read_otadata", help="read otadata partition")
|
||||
subparsers.add_parser("erase_otadata", help="erase otadata partition")
|
||||
|
||||
slot_or_name_parser = argparse.ArgumentParser(add_help=False)
|
||||
slot_or_name_parser_args = slot_or_name_parser.add_mutually_exclusive_group()
|
||||
slot_or_name_parser_args.add_argument("--slot", help="slot number of the ota partition", type=int)
|
||||
slot_or_name_parser_args.add_argument("--name", help="name of the ota partition")
|
||||
|
||||
subparsers.add_parser("switch_otadata", help="switch otadata partition", parents=[slot_or_name_parser])
|
||||
|
||||
read_ota_partition_subparser = subparsers.add_parser("read_ota_partition", help="read contents of an ota partition", parents=[slot_or_name_parser])
|
||||
read_ota_partition_subparser.add_argument("--output", help="file to write the contents of the ota partition to")
|
||||
|
||||
write_ota_partition_subparser = subparsers.add_parser("write_ota_partition", help="write contents to an ota partition", parents=[slot_or_name_parser])
|
||||
write_ota_partition_subparser.add_argument("--input", help="file whose contents to write to the ota partition")
|
||||
|
||||
subparsers.add_parser("erase_ota_partition", help="erase contents of an ota partition", parents=[slot_or_name_parser])
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
quiet = args.quiet
|
||||
|
||||
# No operation specified, display help and exit
|
||||
if args.operation is None:
|
||||
if not quiet:
|
||||
parser.print_help()
|
||||
sys.exit(1)
|
||||
|
||||
# Else execute the operation
|
||||
operation_func = globals()[args.operation]
|
||||
|
||||
if quiet:
|
||||
# If exceptions occur, suppress and exit quietly
|
||||
try:
|
||||
operation_func(args)
|
||||
except Exception:
|
||||
sys.exit(2)
|
||||
else:
|
||||
operation_func(args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -3,7 +3,6 @@
|
||||
# partition table
|
||||
# (NB: because of component dependency, we know partition_table
|
||||
# project_include.cmake has already been included.)
|
||||
|
||||
if(OTADATA_PARTITION_OFFSET AND OTADATA_PARTITION_SIZE AND IDF_BUILD_ARTIFACTS)
|
||||
if(${OTADATA_PARTITION_OFFSET})
|
||||
set(BLANK_OTADATA_FILE "ota_data_initial.bin")
|
||||
endif()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
set(COMPONENT_SRCDIRS ".")
|
||||
set(COMPONENT_ADD_INCLUDEDIRS ".")
|
||||
|
||||
set(COMPONENT_REQUIRES unity test_utils app_update bootloader_support nvs_flash)
|
||||
set(COMPONENT_REQUIRES unity app_update bootloader_support nvs_flash)
|
||||
|
||||
register_component()
|
||||
@@ -1,50 +0,0 @@
|
||||
#include <string.h>
|
||||
#include "esp_ota_ops.h"
|
||||
#include "unity.h"
|
||||
|
||||
TEST_CASE("esp_ota_get_app_elf_sha256 test", "[esp_app_desc]")
|
||||
{
|
||||
const int sha256_hex_len = CONFIG_APP_RETRIEVE_LEN_ELF_SHA;
|
||||
char dst[sha256_hex_len + 2];
|
||||
const char fill = 0xcc;
|
||||
int res;
|
||||
size_t len;
|
||||
|
||||
char ref_sha256[sha256_hex_len + 1];
|
||||
const esp_app_desc_t* desc = esp_ota_get_app_description();
|
||||
for (int i = 0; i < sizeof(ref_sha256) / 2; ++i) {
|
||||
snprintf(ref_sha256 + 2*i, 3, "%02x", desc->app_elf_sha256[i]);
|
||||
}
|
||||
ref_sha256[sha256_hex_len] = 0;
|
||||
|
||||
printf("Ref: %s\n", ref_sha256);
|
||||
|
||||
memset(dst, fill, sizeof(dst));
|
||||
len = sizeof(dst);
|
||||
res = esp_ota_get_app_elf_sha256(dst, len);
|
||||
printf("%d: %s (%d)\n", len, dst, res);
|
||||
TEST_ASSERT_EQUAL(sha256_hex_len + 1, res);
|
||||
TEST_ASSERT_EQUAL(0, memcmp(dst, ref_sha256, res - 1));
|
||||
TEST_ASSERT_EQUAL_HEX(0, dst[sha256_hex_len]);
|
||||
TEST_ASSERT_EQUAL_HEX(fill, dst[sha256_hex_len + 1]);
|
||||
|
||||
memset(dst, fill, sizeof(dst));
|
||||
len = 9;
|
||||
res = esp_ota_get_app_elf_sha256(dst, len);
|
||||
printf("%d: %s (%d)\n", len, dst, res);
|
||||
TEST_ASSERT_EQUAL(9, res);
|
||||
TEST_ASSERT_EQUAL(0, memcmp(dst, ref_sha256, res - 1));
|
||||
TEST_ASSERT_EQUAL_HEX(0, dst[8]);
|
||||
TEST_ASSERT_EQUAL_HEX(fill, dst[9]);
|
||||
|
||||
memset(dst, fill, sizeof(dst));
|
||||
len = 8;
|
||||
res = esp_ota_get_app_elf_sha256(dst, len);
|
||||
printf("%d: %s (%d)\n", len, dst, res);
|
||||
// should output even number of characters plus '\0'
|
||||
TEST_ASSERT_EQUAL(7, res);
|
||||
TEST_ASSERT_EQUAL(0, memcmp(dst, ref_sha256, res - 1));
|
||||
TEST_ASSERT_EQUAL_HEX(0, dst[6]);
|
||||
TEST_ASSERT_EQUAL_HEX(fill, dst[7]);
|
||||
TEST_ASSERT_EQUAL_HEX(fill, dst[8]);
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <unity.h>
|
||||
#include <test_utils.h>
|
||||
#include <esp_ota_ops.h>
|
||||
#include "bootloader_common.h"
|
||||
|
||||
|
||||
/* These OTA tests currently don't assume an OTA partition exists
|
||||
on the device, so they're a bit limited
|
||||
@@ -84,26 +84,3 @@ TEST_CASE("esp_ota_get_next_update_partition logic", "[ota]")
|
||||
TEST_ASSERT_EQUAL_PTR(ota_0, p);
|
||||
}
|
||||
|
||||
TEST_CASE("esp_ota_get_partition_description ", "[ota]")
|
||||
{
|
||||
const esp_partition_t *running = esp_ota_get_running_partition();
|
||||
TEST_ASSERT_NOT_NULL(running);
|
||||
esp_app_desc_t app_desc1, app_desc2;
|
||||
TEST_ESP_OK(esp_ota_get_partition_description(running, &app_desc1));
|
||||
const esp_partition_pos_t running_pos = {
|
||||
.offset = running->address,
|
||||
.size = running->size
|
||||
};
|
||||
TEST_ESP_OK(bootloader_common_get_partition_description(&running_pos, &app_desc2));
|
||||
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE((uint8_t *)&app_desc1, (uint8_t *)&app_desc2, sizeof(app_desc1), "must be the same");
|
||||
|
||||
const esp_partition_t *not_app = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_OTA, NULL);
|
||||
TEST_ASSERT_NOT_NULL(not_app);
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_ota_get_partition_description(not_app, &app_desc1));
|
||||
const esp_partition_pos_t not_app_pos = {
|
||||
.offset = not_app->address,
|
||||
.size = not_app->size
|
||||
};
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, bootloader_common_get_partition_description(¬_app_pos, &app_desc1));
|
||||
}
|
||||
|
||||
@@ -237,12 +237,6 @@ static void reset_output_pin(uint32_t num_pin)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void mark_app_valid(void)
|
||||
{
|
||||
#ifdef CONFIG_APP_ROLLBACK_ENABLE
|
||||
TEST_ESP_OK(esp_ota_mark_app_valid_cancel_rollback());
|
||||
#endif
|
||||
}
|
||||
|
||||
/* @brief Checks and prepares the partition so that the factory app is launched after that.
|
||||
*/
|
||||
@@ -268,18 +262,15 @@ static void test_flow1(void)
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
mark_app_valid();
|
||||
copy_current_app_to_next_part_and_reboot(cur_app);
|
||||
break;
|
||||
case 4:
|
||||
ESP_LOGI(TAG, "OTA1");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_1, cur_app->subtype);
|
||||
mark_app_valid();
|
||||
copy_current_app_to_next_part_and_reboot(cur_app);
|
||||
break;
|
||||
case 5:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
mark_app_valid();
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
erase_ota_data();
|
||||
break;
|
||||
@@ -295,7 +286,7 @@ static void test_flow1(void)
|
||||
// 3 Stage: run OTA0 -> check it -> copy OTA0 to OTA1 -> reboot --//--
|
||||
// 4 Stage: run OTA1 -> check it -> copy OTA1 to OTA0 -> reboot --//--
|
||||
// 5 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, OTA1, OTA0", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow1, test_flow1, test_flow1, test_flow1);
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, OTA1, OTA0", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow1, test_flow1, test_flow1, test_flow1);
|
||||
|
||||
static void test_flow2(void)
|
||||
{
|
||||
@@ -311,7 +302,6 @@ static void test_flow2(void)
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
mark_app_valid();
|
||||
copy_current_app_to_next_part(cur_app, get_next_update_partition());
|
||||
corrupt_ota_data(CORR_CRC_1_SECTOR_OTA_DATA);
|
||||
reboot_as_deep_sleep();
|
||||
@@ -332,7 +322,7 @@ static void test_flow2(void)
|
||||
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> corrupt ota data -> reboot --//--
|
||||
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, corrupt ota_sec1, factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow2, test_flow2, test_flow2);
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, corrupt ota_sec1, factory", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow2, test_flow2, test_flow2);
|
||||
|
||||
static void test_flow3(void)
|
||||
{
|
||||
@@ -348,13 +338,11 @@ static void test_flow3(void)
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
mark_app_valid();
|
||||
copy_current_app_to_next_part_and_reboot(cur_app);
|
||||
break;
|
||||
case 4:
|
||||
ESP_LOGI(TAG, "OTA1");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_1, cur_app->subtype);
|
||||
mark_app_valid();
|
||||
copy_current_app_to_next_part(cur_app, get_next_update_partition());
|
||||
corrupt_ota_data(CORR_CRC_2_SECTOR_OTA_DATA);
|
||||
reboot_as_deep_sleep();
|
||||
@@ -376,7 +364,7 @@ static void test_flow3(void)
|
||||
// 3 Stage: run OTA0 -> check it -> copy OTA0 to OTA1 -> reboot --//--
|
||||
// 3 Stage: run OTA1 -> check it -> corrupt ota sector2 -> reboot --//--
|
||||
// 4 Stage: run OTA0 -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, OTA1, currupt ota_sec2, OTA0", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow3, test_flow3, test_flow3, test_flow3);
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, OTA1, currupt ota_sec2, OTA0", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow3, test_flow3, test_flow3, test_flow3);
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_FACTORY_RESET
|
||||
#define STORAGE_NAMESPACE "update_ota"
|
||||
@@ -406,7 +394,7 @@ static void test_flow4(void)
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
mark_app_valid();
|
||||
|
||||
TEST_ESP_OK(nvs_flash_init());
|
||||
TEST_ESP_OK(nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &handle));
|
||||
TEST_ESP_OK(nvs_get_i32(handle, "boot_count", &boot_count_nvs));
|
||||
@@ -443,7 +431,7 @@ static void test_flow4(void)
|
||||
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> set_pin_factory_reset -> reboot --//--
|
||||
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, sets pin_factory_reset, factory", "[app_update][timeout=90][ignore][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow4, test_flow4, test_flow4);
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, OTA0, sets pin_factory_reset, factory", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow4, test_flow4, test_flow4);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BOOTLOADER_APP_TEST
|
||||
@@ -486,247 +474,5 @@ static void test_flow5(void)
|
||||
// 2 Stage: run factory -> check it -> copy factory to Test and set pin_test_app -> reboot --//--
|
||||
// 3 Stage: run test -> check it -> reset pin_test_app -> reboot --//--
|
||||
// 4 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, test, factory", "[app_update][timeout=90][ignore][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow5, test_flow5, test_flow5);
|
||||
TEST_CASE_MULTIPLE_STAGES("Switching between factory, test, factory", "[app_update][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET]", start_test, test_flow5, test_flow5, test_flow5);
|
||||
#endif
|
||||
|
||||
static const esp_partition_t* app_update(void)
|
||||
{
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
const esp_partition_t* update_partition = esp_ota_get_next_update_partition(NULL);
|
||||
TEST_ASSERT_NOT_NULL(update_partition);
|
||||
esp_ota_handle_t update_handle = 0;
|
||||
TEST_ESP_OK(esp_ota_begin(update_partition, OTA_SIZE_UNKNOWN, &update_handle));
|
||||
copy_app_partition(update_handle, cur_app);
|
||||
TEST_ESP_OK(esp_ota_end(update_handle));
|
||||
TEST_ESP_OK(esp_ota_set_boot_partition(update_partition));
|
||||
return update_partition;
|
||||
}
|
||||
|
||||
|
||||
static void test_rollback1(void)
|
||||
{
|
||||
boot_count++;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
esp_ota_img_states_t ota_state = 0x5555AAAA;
|
||||
const esp_partition_t* update_partition = NULL;
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
update_partition = app_update();
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(update_partition, &ota_state));
|
||||
#ifndef CONFIG_APP_ROLLBACK_ENABLE
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_NEW, ota_state);
|
||||
#endif
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
#ifndef CONFIG_APP_ROLLBACK_ENABLE
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_PENDING_VERIFY, ota_state);
|
||||
#endif
|
||||
TEST_ESP_OK(esp_ota_mark_app_valid_cancel_rollback());
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_VALID, ota_state);
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 4:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_VALID, ota_state);
|
||||
TEST_ESP_OK(esp_ota_mark_app_invalid_rollback_and_reboot());
|
||||
break;
|
||||
default:
|
||||
erase_ota_data();
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_rollback1_1(void)
|
||||
{
|
||||
boot_count = 5;
|
||||
esp_ota_img_states_t ota_state = 0x5555AAAA;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
|
||||
const esp_partition_t *invalid_partition = esp_ota_get_last_invalid_partition();
|
||||
const esp_partition_t* next_update_partition = esp_ota_get_next_update_partition(NULL);
|
||||
TEST_ASSERT_NOT_NULL(invalid_partition);
|
||||
TEST_ASSERT_NOT_NULL(next_update_partition);
|
||||
TEST_ASSERT_EQUAL_PTR(invalid_partition, next_update_partition);
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(invalid_partition, &ota_state));
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_INVALID, ota_state);
|
||||
|
||||
erase_ota_data();
|
||||
}
|
||||
|
||||
// 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
|
||||
// 2 Stage: run factory -> check it -> copy factory to next app slot -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> esp_ota_mark_app_valid_cancel_rollback() -> reboot --//--
|
||||
// 4 Stage: run OTA0 -> check it -> esp_ota_mark_app_invalid_rollback_and_reboot() -> reboot
|
||||
// 5 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Test rollback. factory, OTA0, OTA0, rollback -> factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_rollback1, test_rollback1, test_rollback1, test_rollback1_1);
|
||||
|
||||
static void test_rollback2(void)
|
||||
{
|
||||
boot_count++;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
esp_ota_img_states_t ota_state = 0x5555AAAA;
|
||||
const esp_partition_t* update_partition = NULL;
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
update_partition = app_update();
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(update_partition, &ota_state));
|
||||
#ifndef CONFIG_APP_ROLLBACK_ENABLE
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_NEW, ota_state);
|
||||
#endif
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
#ifndef CONFIG_APP_ROLLBACK_ENABLE
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_PENDING_VERIFY, ota_state);
|
||||
#endif
|
||||
TEST_ESP_OK(esp_ota_mark_app_valid_cancel_rollback());
|
||||
TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_VALID, ota_state);
|
||||
update_partition = app_update();
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(update_partition, &ota_state));
|
||||
#ifndef CONFIG_APP_ROLLBACK_ENABLE
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_NEW, ota_state);
|
||||
#endif
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 4:
|
||||
ESP_LOGI(TAG, "OTA1");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_1, cur_app->subtype);
|
||||
TEST_ASSERT_NULL(esp_ota_get_last_invalid_partition());
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
#ifndef CONFIG_APP_ROLLBACK_ENABLE
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_UNDEFINED, ota_state);
|
||||
TEST_ESP_OK(esp_ota_mark_app_invalid_rollback_and_reboot());
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_PENDING_VERIFY, ota_state);
|
||||
reboot_as_deep_sleep();
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
erase_ota_data();
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_rollback2_1(void)
|
||||
{
|
||||
boot_count = 5;
|
||||
esp_ota_img_states_t ota_state = 0x5555AAAA;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
|
||||
const esp_partition_t *invalid_partition = esp_ota_get_last_invalid_partition();
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_1, invalid_partition->subtype);
|
||||
const esp_partition_t* next_update_partition = esp_ota_get_next_update_partition(NULL);
|
||||
TEST_ASSERT_NOT_NULL(invalid_partition);
|
||||
TEST_ASSERT_NOT_NULL(next_update_partition);
|
||||
TEST_ASSERT_EQUAL_PTR(invalid_partition, next_update_partition);
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(cur_app, &ota_state));
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_VALID, ota_state);
|
||||
TEST_ESP_OK(esp_ota_get_state_partition(invalid_partition, &ota_state));
|
||||
#ifndef CONFIG_APP_ROLLBACK_ENABLE
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_INVALID, ota_state);
|
||||
#else
|
||||
TEST_ASSERT_EQUAL(ESP_OTA_IMG_ABORTED, ota_state);
|
||||
#endif
|
||||
erase_ota_data();
|
||||
}
|
||||
|
||||
// 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
|
||||
// 2 Stage: run factory -> check it -> copy factory to next app slot -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> esp_ota_mark_app_valid_cancel_rollback(), copy to next app slot -> reboot --//--
|
||||
// 4 Stage: run OTA1 -> check it -> PENDING_VERIFY/esp_ota_mark_app_invalid_rollback_and_reboot() -> reboot
|
||||
// 5 Stage: run OTA0(rollback) -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Test rollback. factory, OTA0, OTA1, rollback -> OTA0", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_rollback2, test_rollback2, test_rollback2, test_rollback2_1);
|
||||
|
||||
static void test_erase_last_app_flow(void)
|
||||
{
|
||||
boot_count++;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
switch (boot_count) {
|
||||
case 2:
|
||||
ESP_LOGI(TAG, "Factory");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
app_update();
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 3:
|
||||
ESP_LOGI(TAG, "OTA0");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_0, cur_app->subtype);
|
||||
mark_app_valid();
|
||||
app_update();
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
case 4:
|
||||
ESP_LOGI(TAG, "OTA1");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_OTA_1, cur_app->subtype);
|
||||
TEST_ESP_OK(esp_ota_erase_last_boot_app_partition());
|
||||
TEST_ESP_OK(esp_ota_mark_app_invalid_rollback_and_reboot());
|
||||
reboot_as_deep_sleep();
|
||||
break;
|
||||
default:
|
||||
erase_ota_data();
|
||||
TEST_FAIL_MESSAGE("Unexpected stage");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void test_erase_last_app_rollback(void)
|
||||
{
|
||||
boot_count = 5;
|
||||
ESP_LOGI(TAG, "boot count %d", boot_count);
|
||||
const esp_partition_t *cur_app = get_running_firmware();
|
||||
ESP_LOGI(TAG, "erase_last_app");
|
||||
TEST_ASSERT_EQUAL(ESP_PARTITION_SUBTYPE_APP_FACTORY, cur_app->subtype);
|
||||
TEST_ESP_ERR(ESP_FAIL, esp_ota_erase_last_boot_app_partition());
|
||||
erase_ota_data();
|
||||
}
|
||||
|
||||
// 1 Stage: After POWER_RESET erase OTA_DATA for this test -> reboot through deep sleep.
|
||||
// 2 Stage: run factory -> check it -> copy factory to OTA0 -> reboot --//--
|
||||
// 3 Stage: run OTA0 -> check it -> copy factory to OTA1 -> reboot --//--
|
||||
// 4 Stage: run OTA1 -> check it -> erase OTA0 and rollback -> reboot
|
||||
// 5 Stage: run factory -> check it -> erase OTA_DATA for next tests -> PASS
|
||||
TEST_CASE_MULTIPLE_STAGES("Test erase_last_boot_app_partition. factory, OTA1, OTA0, factory", "[app_update][timeout=90][reset=DEEPSLEEP_RESET, DEEPSLEEP_RESET, DEEPSLEEP_RESET, SW_CPU_RESET]", start_test, test_erase_last_app_flow, test_erase_last_app_flow, test_erase_last_app_flow, test_erase_last_app_rollback);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
menuconfig AWS_IOT_SDK
|
||||
bool "Amazon Web Services IoT Platform"
|
||||
help
|
||||
Select this option to enable support for the AWS IoT platform,
|
||||
via the esp-idf component for the AWS IoT Device C SDK.
|
||||
Select this option to enable support for the AWS IoT platform,
|
||||
via the esp-idf component for the AWS IoT Device C SDK.
|
||||
|
||||
config AWS_IOT_MQTT_HOST
|
||||
string "AWS IoT Endpoint Hostname"
|
||||
@@ -86,79 +86,74 @@ config AWS_IOT_MQTT_MAX_RECONNECT_WAIT_INTERVAL
|
||||
menu "Thing Shadow"
|
||||
depends on AWS_IOT_SDK
|
||||
|
||||
config AWS_IOT_OVERRIDE_THING_SHADOW_RX_BUFFER
|
||||
bool "Override Shadow RX buffer size"
|
||||
depends on AWS_IOT_SDK
|
||||
default n
|
||||
help
|
||||
Allows setting a different Thing Shadow RX buffer
|
||||
size. This is the maximum size of a Thing Shadow
|
||||
message in bytes, plus one.
|
||||
config AWS_IOT_OVERRIDE_THING_SHADOW_RX_BUFFER
|
||||
bool "Override Shadow RX buffer size"
|
||||
depends on AWS_IOT_SDK
|
||||
default n
|
||||
help
|
||||
Allows setting a different Thing Shadow RX buffer
|
||||
size. This is the maximum size of a Thing Shadow
|
||||
message in bytes, plus one.
|
||||
|
||||
If not overridden, the default value is the MQTT RX Buffer length plus one. If overriden, do not set
|
||||
higher than the default value.
|
||||
If not overridden, the default value is the MQTT RX Buffer length plus one. If overriden, do not set higher than the default value.
|
||||
|
||||
config AWS_IOT_SHADOW_MAX_SIZE_OF_RX_BUFFER
|
||||
int "Maximum RX Buffer (bytes)"
|
||||
depends on AWS_IOT_OVERRIDE_THING_SHADOW_RX_BUFFER
|
||||
default 513
|
||||
range 32 65536
|
||||
help
|
||||
Allows setting a different Thing Shadow RX buffer size.
|
||||
This is the maximum size of a Thing Shadow message in bytes,
|
||||
plus one.
|
||||
config AWS_IOT_SHADOW_MAX_SIZE_OF_RX_BUFFER
|
||||
int "Maximum RX Buffer (bytes)"
|
||||
depends on AWS_IOT_OVERRIDE_THING_SHADOW_RX_BUFFER
|
||||
default 513
|
||||
range 32 65536
|
||||
help
|
||||
Allows setting a different Thing Shadow RX buffer size.
|
||||
This is the maximum size of a Thing Shadow message in bytes,
|
||||
plus one.
|
||||
|
||||
|
||||
config AWS_IOT_SHADOW_MAX_SIZE_OF_UNIQUE_CLIENT_ID_BYTES
|
||||
int "Maximum unique client ID size (bytes)"
|
||||
depends on AWS_IOT_SDK
|
||||
default 80
|
||||
range 4 1000
|
||||
help
|
||||
Maximum size of the Unique Client Id.
|
||||
config AWS_IOT_SHADOW_MAX_SIZE_OF_UNIQUE_CLIENT_ID_BYTES
|
||||
int "Maximum unique client ID size (bytes)"
|
||||
depends on AWS_IOT_SDK
|
||||
default 80
|
||||
range 4 1000
|
||||
help
|
||||
Maximum size of the Unique Client Id.
|
||||
|
||||
config AWS_IOT_SHADOW_MAX_SIMULTANEOUS_ACKS
|
||||
int "Maximum simultaneous responses"
|
||||
depends on AWS_IOT_SDK
|
||||
default 10
|
||||
range 1 100
|
||||
help
|
||||
At any given time we will wait for this many responses. This will correlate to the rate at which the
|
||||
shadow actions are requested
|
||||
config AWS_IOT_SHADOW_MAX_SIMULTANEOUS_ACKS
|
||||
int "Maximum simultaneous responses"
|
||||
depends on AWS_IOT_SDK
|
||||
default 10
|
||||
range 1 100
|
||||
help
|
||||
At any given time we will wait for this many responses. This will correlate to the rate at which the shadow actions are requested
|
||||
|
||||
config AWS_IOT_SHADOW_MAX_SIMULTANEOUS_THINGNAMES
|
||||
int "Maximum simultaneous Thing Name operations"
|
||||
depends on AWS_IOT_SDK
|
||||
default 10
|
||||
range 1 100
|
||||
help
|
||||
We could perform shadow action on any thing Name and this is maximum Thing Names we can act on at any
|
||||
given time
|
||||
config AWS_IOT_SHADOW_MAX_SIMULTANEOUS_THINGNAMES
|
||||
int "Maximum simultaneous Thing Name operations"
|
||||
depends on AWS_IOT_SDK
|
||||
default 10
|
||||
range 1 100
|
||||
help
|
||||
We could perform shadow action on any thing Name and this is maximum Thing Names we can act on at any given time
|
||||
|
||||
config AWS_IOT_SHADOW_MAX_JSON_TOKEN_EXPECTED
|
||||
int "Maximum expected JSON tokens"
|
||||
depends on AWS_IOT_SDK
|
||||
default 120
|
||||
help
|
||||
These are the max tokens that is expected to be in the Shadow JSON document. Includes the metadata which
|
||||
is published
|
||||
config AWS_IOT_SHADOW_MAX_JSON_TOKEN_EXPECTED
|
||||
int "Maximum expected JSON tokens"
|
||||
depends on AWS_IOT_SDK
|
||||
default 120
|
||||
help
|
||||
These are the max tokens that is expected to be in the Shadow JSON document. Includes the metadata which is published
|
||||
|
||||
config AWS_IOT_SHADOW_MAX_SHADOW_TOPIC_LENGTH_WITHOUT_THINGNAME
|
||||
int "Maximum topic length (not including Thing Name)"
|
||||
depends on AWS_IOT_SDK
|
||||
default 60
|
||||
range 10 1000
|
||||
help
|
||||
All shadow actions have to be published or subscribed to a topic which is of the format
|
||||
$aws/things/{thingName}/shadow/update/accepted. This refers to the size of the topic without the Thing
|
||||
Name
|
||||
config AWS_IOT_SHADOW_MAX_SHADOW_TOPIC_LENGTH_WITHOUT_THINGNAME
|
||||
int "Maximum topic length (not including Thing Name)"
|
||||
depends on AWS_IOT_SDK
|
||||
default 60
|
||||
range 10 1000
|
||||
help
|
||||
All shadow actions have to be published or subscribed to a topic which is of the format $aws/things/{thingName}/shadow/update/accepted. This refers to the size of the topic without the Thing Name
|
||||
|
||||
config AWS_IOT_SHADOW_MAX_SIZE_OF_THING_NAME
|
||||
int "Maximum Thing Name length"
|
||||
depends on AWS_IOT_SDK
|
||||
default 20
|
||||
range 4 1000
|
||||
help
|
||||
Maximum length of a Thing Name.
|
||||
config AWS_IOT_SHADOW_MAX_SIZE_OF_THING_NAME
|
||||
int "Maximum Thing Name length"
|
||||
depends on AWS_IOT_SDK
|
||||
default 20
|
||||
range 4 1000
|
||||
help
|
||||
Maximum length of a Thing Name.
|
||||
|
||||
endmenu # Thing Shadow
|
||||
|
||||
|
||||
@@ -236,7 +236,6 @@ IoT_Error_t iot_tls_connect(Network *pNetwork, TLSConnectParams *params) {
|
||||
|
||||
mbedtls_ssl_conf_read_timeout(&(tlsDataParams->conf), pNetwork->tlsConnectParams.timeout_ms);
|
||||
|
||||
#ifdef CONFIG_MBEDTLS_SSL_ALPN
|
||||
/* Use the AWS IoT ALPN extension for MQTT, if port 443 is requested */
|
||||
if (pNetwork->tlsConnectParams.DestinationPort == 443) {
|
||||
const char *alpnProtocols[] = { "x-amzn-mqtt-ca", NULL };
|
||||
@@ -245,7 +244,6 @@ IoT_Error_t iot_tls_connect(Network *pNetwork, TLSConnectParams *params) {
|
||||
return SSL_CONNECTION_ERROR;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if((ret = mbedtls_ssl_setup(&(tlsDataParams->ssl), &(tlsDataParams->conf))) != 0) {
|
||||
ESP_LOGE(TAG, "failed! mbedtls_ssl_setup returned -0x%x", -ret);
|
||||
|
||||
@@ -1,527 +1,429 @@
|
||||
menu "Bootloader config"
|
||||
choice LOG_BOOTLOADER_LEVEL
|
||||
bool "Bootloader log verbosity"
|
||||
default LOG_BOOTLOADER_LEVEL_INFO
|
||||
help
|
||||
Specify how much output to see in bootloader logs.
|
||||
choice LOG_BOOTLOADER_LEVEL
|
||||
bool "Bootloader log verbosity"
|
||||
default LOG_BOOTLOADER_LEVEL_INFO
|
||||
help
|
||||
Specify how much output to see in bootloader logs.
|
||||
|
||||
config LOG_BOOTLOADER_LEVEL_NONE
|
||||
bool "No output"
|
||||
config LOG_BOOTLOADER_LEVEL_ERROR
|
||||
bool "Error"
|
||||
config LOG_BOOTLOADER_LEVEL_WARN
|
||||
bool "Warning"
|
||||
config LOG_BOOTLOADER_LEVEL_INFO
|
||||
bool "Info"
|
||||
config LOG_BOOTLOADER_LEVEL_DEBUG
|
||||
bool "Debug"
|
||||
config LOG_BOOTLOADER_LEVEL_VERBOSE
|
||||
bool "Verbose"
|
||||
endchoice
|
||||
config LOG_BOOTLOADER_LEVEL_NONE
|
||||
bool "No output"
|
||||
config LOG_BOOTLOADER_LEVEL_ERROR
|
||||
bool "Error"
|
||||
config LOG_BOOTLOADER_LEVEL_WARN
|
||||
bool "Warning"
|
||||
config LOG_BOOTLOADER_LEVEL_INFO
|
||||
bool "Info"
|
||||
config LOG_BOOTLOADER_LEVEL_DEBUG
|
||||
bool "Debug"
|
||||
config LOG_BOOTLOADER_LEVEL_VERBOSE
|
||||
bool "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
|
||||
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
|
||||
|
||||
config BOOTLOADER_SPI_WP_PIN
|
||||
int "SPI Flash WP Pin when customising pins via eFuse (read help)"
|
||||
range 0 33
|
||||
default 7
|
||||
depends on FLASHMODE_QIO || FLASHMODE_QOUT
|
||||
help
|
||||
This value is ignored unless flash mode is set to QIO or QOUT *and* the SPI flash pins have been
|
||||
overriden by setting the eFuses SPI_PAD_CONFIG_xxx.
|
||||
config BOOTLOADER_SPI_WP_PIN
|
||||
int "SPI Flash WP Pin when customising pins via efuse (read help)"
|
||||
range 0 33
|
||||
default 7
|
||||
depends on FLASHMODE_QIO || FLASHMODE_QOUT
|
||||
help
|
||||
This value is ignored unless flash mode is set to QIO or QOUT *and* the SPI flash pins have been
|
||||
overriden by setting the efuses SPI_PAD_CONFIG_xxx.
|
||||
|
||||
When this is the case, the eFuse config only defines 3 of the 4 Quad I/O data pins. The WP pin (aka ESP32
|
||||
pin "SD_DATA_3" or SPI flash pin "IO2") is not specified in eFuse. That pin number is compiled into the
|
||||
bootloader instead.
|
||||
When this is the case, the Efuse config only defines 3 of the 4 Quad I/O data pins. The WP pin (aka ESP32
|
||||
pin "SD_DATA_3" or SPI flash pin "IO2") is not specified in Efuse. That pin number is compiled into the bootloader
|
||||
instead.
|
||||
|
||||
The default value (GPIO 7) is correct for WP pin on ESP32-D2WD integrated flash.
|
||||
The default value (GPIO 7) is correct for WP pin on ESP32-D2WD integrated flash.
|
||||
|
||||
choice BOOTLOADER_VDDSDIO_BOOST
|
||||
bool "VDDSDIO LDO voltage"
|
||||
default BOOTLOADER_VDDSDIO_BOOST_1_9V
|
||||
help
|
||||
If this option is enabled, and VDDSDIO LDO is set to 1.8V (using eFuse
|
||||
or MTDI bootstrapping pin), bootloader will change LDO settings to
|
||||
output 1.9V instead. This helps prevent flash chip from browning out
|
||||
during flash programming operations.
|
||||
choice BOOTLOADER_VDDSDIO_BOOST
|
||||
bool "VDDSDIO LDO voltage"
|
||||
default BOOTLOADER_VDDSDIO_BOOST_1_9V
|
||||
help
|
||||
If this option is enabled, and VDDSDIO LDO is set to 1.8V (using EFUSE
|
||||
or MTDI bootstrapping pin), bootloader will change LDO settings to
|
||||
output 1.9V instead. This helps prevent flash chip from browning out
|
||||
during flash programming operations.
|
||||
|
||||
This option has no effect if VDDSDIO is set to 3.3V, or if the internal
|
||||
VDDSDIO regulator is disabled via eFuse.
|
||||
This option has no effect if VDDSDIO is set to 3.3V, or if the internal
|
||||
VDDSDIO regulator is disabled via efuse.
|
||||
|
||||
config BOOTLOADER_VDDSDIO_BOOST_1_8V
|
||||
bool "1.8V"
|
||||
depends on !ESPTOOLPY_FLASHFREQ_80M
|
||||
config BOOTLOADER_VDDSDIO_BOOST_1_9V
|
||||
bool "1.9V"
|
||||
endchoice
|
||||
config BOOTLOADER_VDDSDIO_BOOST_1_8V
|
||||
bool "1.8V"
|
||||
depends on !ESPTOOLPY_FLASHFREQ_80M
|
||||
config BOOTLOADER_VDDSDIO_BOOST_1_9V
|
||||
bool "1.9V"
|
||||
endchoice
|
||||
|
||||
config BOOTLOADER_FACTORY_RESET
|
||||
bool "GPIO triggers factory reset"
|
||||
default N
|
||||
help
|
||||
Allows to reset the device to factory settings:
|
||||
- clear one or more data partitions;
|
||||
- boot from "factory" partition.
|
||||
The factory reset will occur if there is a GPIO input pulled low while device starts up.
|
||||
See settings below.
|
||||
config BOOTLOADER_FACTORY_RESET
|
||||
bool "GPIO triggers factory reset"
|
||||
default N
|
||||
help
|
||||
Allows to reset the device to factory settings:
|
||||
- clear one or more data partitions;
|
||||
- boot from "factory" partition.
|
||||
The factory reset will occur if there is a GPIO input pulled low while device starts up.
|
||||
See settings below.
|
||||
|
||||
config BOOTLOADER_NUM_PIN_FACTORY_RESET
|
||||
int "Number of the GPIO input for factory reset"
|
||||
depends on BOOTLOADER_FACTORY_RESET
|
||||
range 0 39
|
||||
default 4
|
||||
help
|
||||
The selected GPIO will be configured as an input with internal pull-up enabled.
|
||||
To trigger a factory reset, this GPIO must be pulled low on reset.
|
||||
Note that GPIO34-39 do not have an internal pullup and an external one must be provided.
|
||||
config BOOTLOADER_NUM_PIN_FACTORY_RESET
|
||||
int "Number of the GPIO input for factory reset"
|
||||
depends on BOOTLOADER_FACTORY_RESET
|
||||
range 0 39
|
||||
default 4
|
||||
help
|
||||
The selected GPIO will be configured as an input with internal pull-up enabled.
|
||||
To trigger a factory reset, this GPIO must be pulled low on reset.
|
||||
Note that GPIO34-39 do not have an internal pullup and an external one must be provided.
|
||||
|
||||
config BOOTLOADER_OTA_DATA_ERASE
|
||||
bool "Clear OTA data on factory reset (select factory partition)"
|
||||
depends on BOOTLOADER_FACTORY_RESET
|
||||
help
|
||||
The device will boot from "factory" partition (or OTA slot 0 if no factory partition is present) after a
|
||||
factory reset.
|
||||
config BOOTLOADER_OTA_DATA_ERASE
|
||||
bool "Clear OTA data on factory reset (select factory partition)"
|
||||
depends on BOOTLOADER_FACTORY_RESET
|
||||
help
|
||||
The device will boot from "factory" partition (or OTA slot 0 if no factory partition is present) after a factory reset.
|
||||
|
||||
config BOOTLOADER_DATA_FACTORY_RESET
|
||||
string "Comma-separated names of partitions to clear on factory reset"
|
||||
depends on BOOTLOADER_FACTORY_RESET
|
||||
default "nvs"
|
||||
help
|
||||
Allows customers to select which data partitions will be erased while factory reset.
|
||||
config BOOTLOADER_DATA_FACTORY_RESET
|
||||
string "Comma-separated names of partitions to clear on factory reset"
|
||||
depends on BOOTLOADER_FACTORY_RESET
|
||||
default "nvs"
|
||||
help
|
||||
Allows customers to select which data partitions will be erased while factory reset.
|
||||
|
||||
Specify the names of partitions as a comma-delimited with optional spaces for readability. (Like this: "nvs, phy_init, ...")
|
||||
Make sure that the name specified in the partition table and here are the same.
|
||||
Partitions of type "app" cannot be specified here.
|
||||
|
||||
Specify the names of partitions as a comma-delimited with optional spaces for readability. (Like this:
|
||||
"nvs, phy_init, ...")
|
||||
Make sure that the name specified in the partition table and here are the same.
|
||||
Partitions of type "app" cannot be specified here.
|
||||
config BOOTLOADER_APP_TEST
|
||||
bool "GPIO triggers boot from test app partition"
|
||||
default N
|
||||
help
|
||||
Allows to run the test app from "TEST" partition.
|
||||
A boot from "test" partition will occur if there is a GPIO input pulled low while device starts up.
|
||||
See settings below.
|
||||
|
||||
config BOOTLOADER_APP_TEST
|
||||
bool "GPIO triggers boot from test app partition"
|
||||
default N
|
||||
help
|
||||
Allows to run the test app from "TEST" partition.
|
||||
A boot from "test" partition will occur if there is a GPIO input pulled low while device starts up.
|
||||
See settings below.
|
||||
config BOOTLOADER_NUM_PIN_APP_TEST
|
||||
int "Number of the GPIO input to boot TEST partition"
|
||||
depends on BOOTLOADER_APP_TEST
|
||||
range 0 39
|
||||
default 18
|
||||
help
|
||||
The selected GPIO will be configured as an input with internal pull-up enabled.
|
||||
To trigger a test app, this GPIO must be pulled low on reset.
|
||||
After the GPIO input is deactivated and the device reboots, the old application will boot.
|
||||
(factory or OTA[x]).
|
||||
Note that GPIO34-39 do not have an internal pullup and an external one must be provided.
|
||||
|
||||
config BOOTLOADER_NUM_PIN_APP_TEST
|
||||
int "Number of the GPIO input to boot TEST partition"
|
||||
depends on BOOTLOADER_APP_TEST
|
||||
range 0 39
|
||||
default 18
|
||||
help
|
||||
The selected GPIO will be configured as an input with internal pull-up enabled.
|
||||
To trigger a test app, this GPIO must be pulled low on reset.
|
||||
After the GPIO input is deactivated and the device reboots, the old application will boot.
|
||||
(factory or OTA[x]).
|
||||
Note that GPIO34-39 do not have an internal pullup and an external one must be provided.
|
||||
config BOOTLOADER_HOLD_TIME_GPIO
|
||||
int "Hold time of GPIO for reset/test mode (seconds)"
|
||||
depends on BOOTLOADER_FACTORY_RESET || BOOTLOADER_APP_TEST
|
||||
default 5
|
||||
help
|
||||
The GPIO must be held low continuously for this period of time after reset
|
||||
before a factory reset or test partition boot (as applicable) is performed.
|
||||
|
||||
config BOOTLOADER_HOLD_TIME_GPIO
|
||||
int "Hold time of GPIO for reset/test mode (seconds)"
|
||||
depends on BOOTLOADER_FACTORY_RESET || BOOTLOADER_APP_TEST
|
||||
default 5
|
||||
help
|
||||
The GPIO must be held low continuously for this period of time after reset
|
||||
before a factory reset or test partition boot (as applicable) is performed.
|
||||
config BOOTLOADER_WDT_ENABLE
|
||||
bool "Use RTC watchdog in start code"
|
||||
default y
|
||||
help
|
||||
Tracks the execution time of startup code.
|
||||
If the execution time is exceeded, the RTC_WDT will restart system.
|
||||
It is also useful to prevent a lock up in start code caused by an unstable power source.
|
||||
NOTE: Tracks the execution time starts from the bootloader code - re-set timeout, while selecting the source for slow_clk - and ends calling app_main.
|
||||
Re-set timeout is needed due to WDT uses a SLOW_CLK clock source. After changing a frequency slow_clk a time of WDT needs to re-set for new frequency.
|
||||
slow_clk depends on ESP32_RTC_CLOCK_SOURCE (INTERNAL_RC or EXTERNAL_CRYSTAL).
|
||||
|
||||
config BOOTLOADER_WDT_ENABLE
|
||||
bool "Use RTC watchdog in start code"
|
||||
default y
|
||||
help
|
||||
Tracks the execution time of startup code.
|
||||
If the execution time is exceeded, the RTC_WDT will restart system.
|
||||
It is also useful to prevent a lock up in start code caused by an unstable power source.
|
||||
NOTE: Tracks the execution time starts from the bootloader code - re-set timeout, while selecting the
|
||||
source for slow_clk - and ends calling app_main.
|
||||
Re-set timeout is needed due to WDT uses a SLOW_CLK clock source. After changing a frequency slow_clk a
|
||||
time of WDT needs to re-set for new frequency.
|
||||
slow_clk depends on ESP32_RTC_CLOCK_SOURCE (INTERNAL_RC or EXTERNAL_CRYSTAL).
|
||||
config BOOTLOADER_WDT_DISABLE_IN_USER_CODE
|
||||
bool "Allows RTC watchdog disable in user code"
|
||||
depends on BOOTLOADER_WDT_ENABLE
|
||||
default n
|
||||
help
|
||||
If it is set, the client must itself reset or disable rtc_wdt in their code (app_main()).
|
||||
Otherwise rtc_wdt will be disabled before calling app_main function.
|
||||
Use function rtc_wdt_feed() for resetting counter of rtc_wdt.
|
||||
Use function rtc_wdt_disable() for disabling rtc_wdt.
|
||||
|
||||
config BOOTLOADER_WDT_DISABLE_IN_USER_CODE
|
||||
bool "Allows RTC watchdog disable in user code"
|
||||
depends on BOOTLOADER_WDT_ENABLE
|
||||
default n
|
||||
help
|
||||
If it is set, the client must itself reset or disable rtc_wdt in their code (app_main()).
|
||||
Otherwise rtc_wdt will be disabled before calling app_main function.
|
||||
Use function rtc_wdt_feed() for resetting counter of rtc_wdt.
|
||||
Use function rtc_wdt_disable() for disabling rtc_wdt.
|
||||
|
||||
config BOOTLOADER_WDT_TIME_MS
|
||||
int "Timeout for RTC watchdog (ms)"
|
||||
depends on BOOTLOADER_WDT_ENABLE
|
||||
default 9000
|
||||
range 0 120000
|
||||
help
|
||||
Verify that this parameter is correct and more then the execution time.
|
||||
Pay attention to options such as reset to factory, trigger test partition and encryption on boot
|
||||
- these options can increase the execution time.
|
||||
Note: RTC_WDT will reset while encryption operations will be performed.
|
||||
|
||||
config APP_ROLLBACK_ENABLE
|
||||
bool "Enable app rollback support"
|
||||
default n
|
||||
help
|
||||
After updating the app, the bootloader runs a new app with the "ESP_OTA_IMG_PENDING_VERIFY" state set.
|
||||
This state prevents the re-run of this app. After the first boot of the new app in the user code, the
|
||||
function should be called to confirm the operability of the app or vice versa about its non-operability.
|
||||
If the app is working, then it is marked as valid. Otherwise, it is marked as not valid and rolls back to
|
||||
the previous working app. A reboot is performed, and the app is booted before the software update.
|
||||
Note: If during the first boot a new app the power goes out or the WDT works, then roll back will happen.
|
||||
Rollback is possible only between the apps with the same security versions.
|
||||
|
||||
config APP_ANTI_ROLLBACK
|
||||
bool "Enable app anti-rollback support"
|
||||
depends on APP_ROLLBACK_ENABLE
|
||||
default n
|
||||
help
|
||||
This option prevents rollback to previous firmware/application image with lower security version.
|
||||
|
||||
config APP_SECURE_VERSION
|
||||
int "eFuse secure version of app"
|
||||
depends on APP_ANTI_ROLLBACK
|
||||
default 0
|
||||
help
|
||||
The secure version is the sequence number stored in the header of each firmware.
|
||||
The security version is set in the bootloader, version is recorded in the eFuse field
|
||||
as the number of set ones. The allocated number of bits in the efuse field
|
||||
for storing the security version is limited (see APP_SECURE_VERSION_SIZE_EFUSE_FIELD option).
|
||||
|
||||
Bootloader: When bootloader selects an app to boot, an app is selected that has
|
||||
a security version greater or equal that recorded in eFuse field.
|
||||
The app is booted with a higher (or equal) secure version.
|
||||
|
||||
The security version is worth increasing if in previous versions there is
|
||||
a significant vulnerability and their use is not acceptable.
|
||||
|
||||
Your partition table should has a scheme with ota_0 + ota_1 (without factory).
|
||||
|
||||
config APP_SECURE_VERSION_SIZE_EFUSE_FIELD
|
||||
int "Size of the efuse secure version field"
|
||||
depends on APP_ANTI_ROLLBACK
|
||||
range 1 32
|
||||
default 32
|
||||
help
|
||||
The size of the efuse secure version field. Its length is limited to 32 bits.
|
||||
This determines how many times the security version can be increased.
|
||||
|
||||
config EFUSE_SECURE_VERSION_EMULATE
|
||||
bool "Emulate operations with efuse secure version(only test)"
|
||||
default n
|
||||
depends on APP_ANTI_ROLLBACK
|
||||
help
|
||||
This option allow emulate read/write operations with efuse secure version.
|
||||
It allow to test anti-rollback implemention without permanent write eFuse bits.
|
||||
In partition table should be exist this partition `emul_efuse, data, 5, , 0x2000`.
|
||||
config BOOTLOADER_WDT_TIME_MS
|
||||
int "Timeout for RTC watchdog (ms)"
|
||||
depends on BOOTLOADER_WDT_ENABLE
|
||||
default 9000
|
||||
range 0 120000
|
||||
help
|
||||
Verify that this parameter is correct and more then the execution time.
|
||||
Pay attention to options such as reset to factory, trigger test partition and encryption on boot
|
||||
- these options can increase the execution time.
|
||||
Note: RTC_WDT will reset while encryption operations will be performed.
|
||||
|
||||
endmenu # Bootloader
|
||||
|
||||
|
||||
menu "Security features"
|
||||
visible if !IDF_CMAKE
|
||||
|
||||
# These three are the actual options to check in code,
|
||||
# selected by the displayed options
|
||||
config SECURE_SIGNED_ON_BOOT
|
||||
bool
|
||||
default y
|
||||
depends on SECURE_BOOT_ENABLED || SECURE_SIGNED_ON_BOOT_NO_SECURE_BOOT
|
||||
|
||||
config SECURE_SIGNED_ON_UPDATE
|
||||
bool
|
||||
default y
|
||||
depends on SECURE_BOOT_ENABLED || SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
|
||||
|
||||
config SECURE_SIGNED_APPS
|
||||
bool
|
||||
default y
|
||||
depends on SECURE_SIGNED_ON_BOOT || SECURE_SIGNED_ON_UPDATE
|
||||
|
||||
|
||||
config SECURE_SIGNED_APPS_NO_SECURE_BOOT
|
||||
bool "Require signed app images"
|
||||
default n
|
||||
depends on !SECURE_BOOT_ENABLED
|
||||
help
|
||||
Require apps to be signed to verify their integrity.
|
||||
|
||||
This option uses the same app signature scheme as hardware secure boot, but unlike hardware secure boot it
|
||||
does not prevent the bootloader from being physically updated. This means that the device can be secured
|
||||
against remote network access, but not physical access. Compared to using hardware Secure Boot this option
|
||||
is much simpler to implement.
|
||||
|
||||
config SECURE_SIGNED_ON_BOOT_NO_SECURE_BOOT
|
||||
bool "Bootloader verifies app signatures"
|
||||
default n
|
||||
depends on SECURE_SIGNED_APPS_NO_SECURE_BOOT
|
||||
help
|
||||
If this option is set, the bootloader will be compiled with code to verify that an app is signed before
|
||||
booting it.
|
||||
|
||||
If hardware secure boot is enabled, this option is always enabled and cannot be disabled.
|
||||
If hardware secure boot is not enabled, this option doesn't add significant security by itself so most
|
||||
users will want to leave it disabled.
|
||||
|
||||
config SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
|
||||
bool "Verify app signature on update"
|
||||
default y
|
||||
depends on SECURE_SIGNED_APPS_NO_SECURE_BOOT
|
||||
help
|
||||
If this option is set, any OTA updated apps will have the signature verified before being considered valid.
|
||||
|
||||
When enabled, the signature is automatically checked whenever the esp_ota_ops.h APIs are used for OTA
|
||||
updates, or esp_image_format.h APIs are used to verify apps.
|
||||
|
||||
If hardware secure boot is enabled, this option is always enabled and cannot be disabled.
|
||||
If hardware secure boot is not enabled, this option still adds significant security against network-based
|
||||
attackers by preventing spoofing of OTA updates.
|
||||
|
||||
config SECURE_BOOT_ENABLED
|
||||
bool "Enable hardware secure boot in bootloader (READ DOCS FIRST)"
|
||||
default n
|
||||
help
|
||||
Build a bootloader which enables secure boot on first boot.
|
||||
|
||||
Once enabled, secure boot will not boot a modified bootloader. The bootloader will only load a partition
|
||||
table or boot an app if the data has a verified digital signature. There are implications for reflashing
|
||||
updated apps once secure boot is enabled.
|
||||
|
||||
When enabling secure boot, JTAG and ROM BASIC Interpreter are permanently disabled by default.
|
||||
|
||||
Refer to https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html before enabling.
|
||||
|
||||
choice SECURE_BOOTLOADER_MODE
|
||||
bool "Secure bootloader mode"
|
||||
depends on SECURE_BOOT_ENABLED
|
||||
default SECURE_BOOTLOADER_ONE_TIME_FLASH
|
||||
|
||||
config SECURE_BOOTLOADER_ONE_TIME_FLASH
|
||||
bool "One-time flash"
|
||||
help
|
||||
On first boot, the bootloader will generate a key which is not readable externally or by software. A
|
||||
digest is generated from the bootloader image itself. This digest will be verified on each subsequent
|
||||
boot.
|
||||
|
||||
Enabling this option means that the bootloader cannot be changed after the first time it is booted.
|
||||
# These three are the actual options to check in code,
|
||||
# selected by the displayed options
|
||||
config SECURE_SIGNED_ON_BOOT
|
||||
bool
|
||||
default y
|
||||
depends on SECURE_BOOT_ENABLED || SECURE_SIGNED_ON_BOOT_NO_SECURE_BOOT
|
||||
|
||||
config SECURE_BOOTLOADER_REFLASHABLE
|
||||
bool "Reflashable"
|
||||
help
|
||||
Generate a reusable secure bootloader key, derived (via SHA-256) from the secure boot signing key.
|
||||
config SECURE_SIGNED_ON_UPDATE
|
||||
bool
|
||||
default y
|
||||
depends on SECURE_BOOT_ENABLED || SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
|
||||
|
||||
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_SIGNED_APPS
|
||||
bool
|
||||
default y
|
||||
depends on SECURE_SIGNED_ON_BOOT || SECURE_SIGNED_ON_UPDATE
|
||||
|
||||
config SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
bool "Sign binaries during build"
|
||||
depends on SECURE_SIGNED_APPS
|
||||
default y
|
||||
help
|
||||
Once secure boot or signed app requirement is enabled, app images are required to be signed.
|
||||
|
||||
If enabled (default), these binary files are signed as part of the build process. The file named in
|
||||
"Secure boot private signing key" will be used to sign the image.
|
||||
config SECURE_SIGNED_APPS_NO_SECURE_BOOT
|
||||
bool "Require signed app images"
|
||||
default n
|
||||
depends on !SECURE_BOOT_ENABLED
|
||||
help
|
||||
Require apps to be signed to verify their integrity.
|
||||
|
||||
If disabled, unsigned app/partition data will be built. They must be signed manually using espsecure.py
|
||||
(for example, on a remote signing server.)
|
||||
This option uses the same app signature scheme as hardware secure boot, but unlike hardware secure boot it does not prevent the bootloader from being physically updated. This means that the device can be secured against remote network access, but not physical access. Compared to using hardware Secure Boot this option is much simpler to implement.
|
||||
|
||||
config SECURE_BOOT_SIGNING_KEY
|
||||
string "Secure boot private signing key"
|
||||
depends on SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
default secure_boot_signing_key.pem
|
||||
help
|
||||
Path to the key file used to sign app images.
|
||||
config SECURE_SIGNED_ON_BOOT_NO_SECURE_BOOT
|
||||
bool "Bootloader verifies app signatures"
|
||||
default n
|
||||
depends on SECURE_SIGNED_APPS_NO_SECURE_BOOT
|
||||
help
|
||||
If this option is set, the bootloader will be compiled with code to verify that an app is signed before booting it.
|
||||
|
||||
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
|
||||
If hardware secure boot is enabled, this option is always enabled and cannot be disabled.
|
||||
If hardware secure boot is not enabled, this option doesn't add significant security by itself so most users will want to leave it disabled.
|
||||
|
||||
See https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html for details.
|
||||
|
||||
config SECURE_BOOT_VERIFICATION_KEY
|
||||
string "Secure boot public signature verification key"
|
||||
depends on SECURE_SIGNED_APPS && !SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
default signature_verification_key.bin
|
||||
help
|
||||
Path to a public key file used to verify signed images. This key is compiled into the bootloader and/or
|
||||
app, to verify app images.
|
||||
config SECURE_SIGNED_ON_UPDATE_NO_SECURE_BOOT
|
||||
bool "Verify app signature on update"
|
||||
default y
|
||||
depends on SECURE_SIGNED_APPS_NO_SECURE_BOOT
|
||||
help
|
||||
If this option is set, any OTA updated apps will have the signature verified before being considered valid.
|
||||
|
||||
Key file is in raw binary format, and can be extracted from a
|
||||
PEM formatted private key using the espsecure.py
|
||||
extract_public_key command.
|
||||
When enabled, the signature is automatically checked whenever the esp_ota_ops.h APIs are used for OTA updates,
|
||||
or esp_image_format.h APIs are used to verify apps.
|
||||
|
||||
Refer to https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html before enabling.
|
||||
If hardware secure boot is enabled, this option is always enabled and cannot be disabled.
|
||||
If hardware secure boot is not enabled, this option still adds significant security against network-based attackers by preventing spoofing of OTA updates.
|
||||
|
||||
choice SECURE_BOOTLOADER_KEY_ENCODING
|
||||
bool "Hardware Key Encoding"
|
||||
depends on SECURE_BOOTLOADER_REFLASHABLE
|
||||
default SECURE_BOOTLOADER_NO_ENCODING
|
||||
help
|
||||
config SECURE_BOOT_ENABLED
|
||||
bool "Enable hardware secure boot in bootloader (READ DOCS FIRST)"
|
||||
default n
|
||||
help
|
||||
Build a bootloader which enables secure boot on first boot.
|
||||
|
||||
In reflashable secure bootloader mode, a hardware key is derived from the signing key (with SHA-256) and
|
||||
can be written to eFuse with espefuse.py.
|
||||
Once enabled, secure boot will not boot a modified bootloader. The bootloader will only load a partition table or boot an app if the data has a verified digital signature. There are implications for reflashing updated apps once secure boot is enabled.
|
||||
|
||||
Normally this is a 256-bit key, but if 3/4 Coding Scheme is used on the device then the eFuse key is
|
||||
truncated to 192 bits.
|
||||
When enabling secure boot, JTAG and ROM BASIC Interpreter are permanently disabled by default.
|
||||
|
||||
This configuration item doesn't change any firmware code, it only changes the size of key binary which is
|
||||
generated at build time.
|
||||
|
||||
config SECURE_BOOTLOADER_KEY_ENCODING_256BIT
|
||||
bool "No encoding (256 bit key)"
|
||||
|
||||
config SECURE_BOOTLOADER_KEY_ENCODING_192BIT
|
||||
bool "3/4 encoding (192 bit key)"
|
||||
Refer to https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html before enabling.
|
||||
|
||||
endchoice
|
||||
|
||||
config SECURE_BOOT_INSECURE
|
||||
bool "Allow potentially insecure options"
|
||||
depends on SECURE_BOOT_ENABLED
|
||||
default N
|
||||
help
|
||||
You can disable some of the default protections offered by secure boot, in order to enable testing or a
|
||||
custom combination of security features.
|
||||
|
||||
Only enable these options if you are very sure.
|
||||
|
||||
Refer to https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html before enabling.
|
||||
|
||||
config FLASH_ENCRYPTION_ENABLED
|
||||
bool "Enable flash encryption on boot (READ DOCS FIRST)"
|
||||
default N
|
||||
help
|
||||
If this option is set, flash contents will be encrypted by the bootloader on first boot.
|
||||
|
||||
Note: After first boot, the system will be permanently encrypted. Re-flashing an encrypted
|
||||
system is complicated and not always possible.
|
||||
|
||||
Read https://docs.espressif.com/projects/esp-idf/en/latest/security/flash-encryption.html before enabling.
|
||||
|
||||
config FLASH_ENCRYPTION_INSECURE
|
||||
bool "Allow potentially insecure options"
|
||||
depends on FLASH_ENCRYPTION_ENABLED
|
||||
default N
|
||||
help
|
||||
You can disable some of the default protections offered by flash encryption, in order to enable testing or
|
||||
a custom combination of security features.
|
||||
|
||||
Only enable these options if you are very sure.
|
||||
|
||||
Refer to https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html and
|
||||
https://docs.espressif.com/projects/esp-idf/en/latest/security/flash-encryption.html for details.
|
||||
|
||||
menu "Potentially insecure options"
|
||||
visible if FLASH_ENCRYPTION_INSECURE || SECURE_BOOT_INSECURE
|
||||
|
||||
# NOTE: Options in this menu NEED to have SECURE_BOOT_INSECURE
|
||||
# and/or FLASH_ENCRYPTION_INSECURE in "depends on", as the menu
|
||||
# itself doesn't enable/disable its children (if it's not set,
|
||||
# it's possible for the insecure menu to be disabled but the insecure option
|
||||
# to remain on which is very bad.)
|
||||
|
||||
config SECURE_BOOT_ALLOW_ROM_BASIC
|
||||
bool "Leave ROM BASIC Interpreter available on reset"
|
||||
depends on SECURE_BOOT_INSECURE || FLASH_ENCRYPTION_INSECURE
|
||||
default N
|
||||
help
|
||||
By default, the BASIC ROM Console starts on reset if no valid bootloader is
|
||||
read from the flash.
|
||||
|
||||
When either flash encryption or secure boot are enabled, the default is to
|
||||
disable this BASIC fallback mode permanently via eFuse.
|
||||
|
||||
If this option is set, this eFuse is not burned and the BASIC ROM Console may
|
||||
remain accessible. Only set this option in testing environments.
|
||||
|
||||
config SECURE_BOOT_ALLOW_JTAG
|
||||
bool "Allow JTAG Debugging"
|
||||
depends on SECURE_BOOT_INSECURE || FLASH_ENCRYPTION_INSECURE
|
||||
default N
|
||||
help
|
||||
If not set (default), the bootloader will permanently disable JTAG (across entire chip) on first boot
|
||||
when either secure boot or flash encryption is enabled.
|
||||
|
||||
Setting this option leaves JTAG on for debugging, which negates all protections of flash encryption
|
||||
and some of the protections of secure boot.
|
||||
|
||||
Only set this option in testing environments.
|
||||
|
||||
config SECURE_BOOT_ALLOW_SHORT_APP_PARTITION
|
||||
bool "Allow app partition length not 64KB aligned"
|
||||
depends on SECURE_BOOT_INSECURE
|
||||
help
|
||||
If not set (default), app partition size must be a multiple of 64KB. App images are padded to 64KB
|
||||
length, and the bootloader checks any trailing bytes after the signature (before the next 64KB
|
||||
boundary) have not been written. This is because flash cache maps entire 64KB pages into the address
|
||||
space. This prevents an attacker from appending unverified data after the app image in the flash,
|
||||
causing it to be mapped into the address space.
|
||||
|
||||
Setting this option allows the app partition length to be unaligned, and disables padding of the app
|
||||
image to this length. It is generally not recommended to set this option, unless you have a legacy
|
||||
partitioning scheme which doesn't support 64KB aligned partition lengths.
|
||||
|
||||
config FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_ENCRYPT
|
||||
bool "Leave UART bootloader encryption enabled"
|
||||
depends on FLASH_ENCRYPTION_INSECURE
|
||||
default N
|
||||
help
|
||||
If not set (default), the bootloader will permanently disable UART bootloader encryption access on
|
||||
first boot. If set, the UART bootloader will still be able to access hardware encryption.
|
||||
|
||||
It is recommended to only set this option in testing environments.
|
||||
|
||||
config FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_DECRYPT
|
||||
bool "Leave UART bootloader decryption enabled"
|
||||
depends on FLASH_ENCRYPTION_INSECURE
|
||||
default N
|
||||
help
|
||||
If not set (default), the bootloader will permanently disable UART bootloader decryption access on
|
||||
first boot. If set, the UART bootloader will still be able to access hardware decryption.
|
||||
|
||||
Only set this option in testing environments. Setting this option allows complete bypass of flash
|
||||
encryption.
|
||||
|
||||
config FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_CACHE
|
||||
bool "Leave UART bootloader flash cache enabled"
|
||||
depends on FLASH_ENCRYPTION_INSECURE
|
||||
default N
|
||||
help
|
||||
If not set (default), the bootloader will permanently disable UART bootloader flash cache access on
|
||||
first boot. If set, the UART bootloader will still be able to access the flash cache.
|
||||
|
||||
Only set this option in testing environments.
|
||||
|
||||
endmenu # Potentially Insecure
|
||||
|
||||
config FLASH_ENCRYPTION_DISABLE_PLAINTEXT
|
||||
bool "Disable serial reflashing of plaintext firmware"
|
||||
depends on FLASH_ENCRYPTION_ENABLED
|
||||
default y if SECURE_BOOT_ENABLED
|
||||
default n if !SECURE_BOOT_ENABLED
|
||||
help
|
||||
If this option is enabled, flash encryption is permanently enabled after first boot by write-protecting
|
||||
the FLASH_CRYPT_CNT efuse. This is the recommended configuration for a secure production system.
|
||||
|
||||
If this option is disabled, FLASH_CRYPT_CNT is left writeable and up to 4 plaintext re-flashes are allowed.
|
||||
An attacker with physical access will be able to read out encrypted flash contents until all plaintext
|
||||
re-flashes have been used up.
|
||||
|
||||
If this option is disabled and hardware Secure Boot is enabled, Secure Boot must be configured in
|
||||
Reflashable mode so that a new Secure Boot digest can be flashed at the same time as plaintext firmware.
|
||||
This combination is not secure and should not be used for a production system.
|
||||
choice SECURE_BOOTLOADER_MODE
|
||||
bool "Secure bootloader mode"
|
||||
depends on SECURE_BOOT_ENABLED
|
||||
default SECURE_BOOTLOADER_ONE_TIME_FLASH
|
||||
|
||||
config SECURE_BOOTLOADER_ONE_TIME_FLASH
|
||||
bool "One-time flash"
|
||||
help
|
||||
On first boot, the bootloader will generate a key which is not readable externally or by software. A digest is generated from the bootloader image itself. This digest will be verified on each subsequent boot.
|
||||
|
||||
Enabling this option means that the bootloader cannot be changed after the first time it is booted.
|
||||
|
||||
config SECURE_BOOTLOADER_REFLASHABLE
|
||||
bool "Reflashable"
|
||||
help
|
||||
Generate a reusable secure bootloader key, derived (via SHA-256) from the secure boot signing key.
|
||||
|
||||
This allows the secure bootloader to be re-flashed by anyone with access to the secure boot signing key.
|
||||
|
||||
This option is less secure than one-time flash, because a leak of the digest key from one device allows reflashing of any device that uses it.
|
||||
|
||||
endchoice
|
||||
|
||||
config SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
bool "Sign binaries during build"
|
||||
depends on SECURE_SIGNED_APPS
|
||||
default y
|
||||
help
|
||||
Once secure boot or signed app requirement is enabled, app images are required to be signed.
|
||||
|
||||
If enabled (default), these binary files are signed as part of the build process. The file named in "Secure boot private signing key" will be used to sign the image.
|
||||
|
||||
If disabled, unsigned app/partition data will be built. They must be signed manually using espsecure.py (for example, on a remote signing server.)
|
||||
|
||||
config SECURE_BOOT_SIGNING_KEY
|
||||
string "Secure boot private signing key"
|
||||
depends on SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
default secure_boot_signing_key.pem
|
||||
help
|
||||
Path to the key file used to sign app images.
|
||||
|
||||
Key file is an ECDSA private key (NIST256p curve) in PEM format.
|
||||
|
||||
Path is evaluated relative to the project directory.
|
||||
|
||||
You can generate a new signing key by running the following command:
|
||||
espsecure.py generate_signing_key secure_boot_signing_key.pem
|
||||
|
||||
See docs/security/secure-boot.rst for details.
|
||||
|
||||
config SECURE_BOOT_VERIFICATION_KEY
|
||||
string "Secure boot public signature verification key"
|
||||
depends on SECURE_SIGNED_APPS && !SECURE_BOOT_BUILD_SIGNED_BINARIES
|
||||
default signature_verification_key.bin
|
||||
help
|
||||
Path to a public key file used to verify signed images. This key is compiled into the bootloader and/or app,
|
||||
to verify app images.
|
||||
|
||||
Key file is in raw binary format, and can be extracted from a
|
||||
PEM formatted private key using the espsecure.py
|
||||
extract_public_key command.
|
||||
|
||||
Refer to https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html before enabling.
|
||||
|
||||
choice SECURE_BOOTLOADER_KEY_ENCODING
|
||||
bool "Hardware Key Encoding"
|
||||
depends on SECURE_BOOTLOADER_REFLASHABLE
|
||||
default SECURE_BOOTLOADER_NO_ENCODING
|
||||
help
|
||||
|
||||
In reflashable secure bootloader mode, a hardware key is derived from the signing key (with SHA-256) and can be written to efuse
|
||||
with espefuse.py.
|
||||
|
||||
Normally this is a 256-bit key, but if 3/4 Coding Scheme is used on the device then the efuse key is truncated to 192 bits.
|
||||
|
||||
This configuration item doesn't change any firmware code, it only changes the size of key binary which is generated at build time.
|
||||
|
||||
config SECURE_BOOTLOADER_KEY_ENCODING_256BIT
|
||||
bool "No encoding (256 bit key)"
|
||||
|
||||
config SECURE_BOOTLOADER_KEY_ENCODING_192BIT
|
||||
bool "3/4 encoding (192 bit key)"
|
||||
|
||||
endchoice
|
||||
|
||||
config SECURE_BOOT_INSECURE
|
||||
bool "Allow potentially insecure options"
|
||||
depends on SECURE_BOOT_ENABLED
|
||||
default N
|
||||
help
|
||||
You can disable some of the default protections offered by secure boot, in order to enable testing or a custom combination of security features.
|
||||
|
||||
Only enable these options if you are very sure.
|
||||
|
||||
Refer to https://docs.espressif.com/projects/esp-idf/en/latest/security/secure-boot.html before enabling.
|
||||
|
||||
config FLASH_ENCRYPTION_ENABLED
|
||||
bool "Enable flash encryption on boot (READ DOCS FIRST)"
|
||||
default N
|
||||
help
|
||||
If this option is set, flash contents will be encrypted by the bootloader on first boot.
|
||||
|
||||
Note: After first boot, the system will be permanently encrypted. Re-flashing an encrypted
|
||||
system is complicated and not always possible.
|
||||
|
||||
Read https://docs.espressif.com/projects/esp-idf/en/latest/security/flash-encryption.html before enabling.
|
||||
|
||||
config FLASH_ENCRYPTION_INSECURE
|
||||
bool "Allow potentially insecure options"
|
||||
depends on FLASH_ENCRYPTION_ENABLED
|
||||
default N
|
||||
help
|
||||
You can disable some of the default protections offered by flash encryption, in order to enable testing or a custom combination of security features.
|
||||
|
||||
Only enable these options if you are very sure.
|
||||
|
||||
Refer to docs/security/secure-boot.rst and docs/security/flash-encryption.rst for details.
|
||||
|
||||
menu "Potentially insecure options"
|
||||
visible if FLASH_ENCRYPTION_INSECURE || SECURE_BOOT_INSECURE
|
||||
|
||||
# NOTE: Options in this menu NEED to have SECURE_BOOT_INSECURE
|
||||
# and/or FLASH_ENCRYPTION_INSECURE in "depends on", as the menu
|
||||
# itself doesn't enable/disable its children (if it's not set,
|
||||
# it's possible for the insecure menu to be disabled but the insecure option
|
||||
# to remain on which is very bad.)
|
||||
|
||||
config SECURE_BOOT_ALLOW_ROM_BASIC
|
||||
bool "Leave ROM BASIC Interpreter available on reset"
|
||||
depends on SECURE_BOOT_INSECURE || FLASH_ENCRYPTION_INSECURE
|
||||
default N
|
||||
help
|
||||
By default, the BASIC ROM Console starts on reset if no valid bootloader is
|
||||
read from the flash.
|
||||
|
||||
When either flash encryption or secure boot are enabled, the default is to
|
||||
disable this BASIC fallback mode permanently via efuse.
|
||||
|
||||
If this option is set, this efuse is not burned and the BASIC ROM Console may
|
||||
remain accessible. Only set this option in testing environments.
|
||||
|
||||
config SECURE_BOOT_ALLOW_JTAG
|
||||
bool "Allow JTAG Debugging"
|
||||
depends on SECURE_BOOT_INSECURE || FLASH_ENCRYPTION_INSECURE
|
||||
default N
|
||||
help
|
||||
If not set (default), the bootloader will permanently disable JTAG (across entire chip) on first boot when either secure boot or flash encryption is enabled.
|
||||
|
||||
Setting this option leaves JTAG on for debugging, which negates all protections of flash encryption and some of the protections of secure boot.
|
||||
|
||||
Only set this option in testing environments.
|
||||
|
||||
config SECURE_BOOT_ALLOW_SHORT_APP_PARTITION
|
||||
bool "Allow app partition length not 64KB aligned"
|
||||
depends on SECURE_BOOT_INSECURE
|
||||
help
|
||||
If not set (default), app partition size must be a multiple of 64KB. App images are padded to 64KB length, and the bootloader checks any trailing bytes after the signature (before the next 64KB boundary) have not been written. This is because flash cache maps entire 64KB pages into the address space. This prevents an attacker from appending unverified data after the app image in the flash, causing it to be mapped into the address space.
|
||||
|
||||
Setting this option allows the app partition length to be unaligned, and disables padding of the app image to this length. It is generally not recommended to set this option, unless you have a legacy partitioning scheme which doesn't support 64KB aligned partition lengths.
|
||||
|
||||
config FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_ENCRYPT
|
||||
bool "Leave UART bootloader encryption enabled"
|
||||
depends on FLASH_ENCRYPTION_INSECURE
|
||||
default N
|
||||
help
|
||||
If not set (default), the bootloader will permanently disable UART bootloader encryption access on first boot. If set, the UART bootloader will still be able to access hardware encryption.
|
||||
|
||||
It is recommended to only set this option in testing environments.
|
||||
|
||||
config FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_DECRYPT
|
||||
bool "Leave UART bootloader decryption enabled"
|
||||
depends on FLASH_ENCRYPTION_INSECURE
|
||||
default N
|
||||
help
|
||||
If not set (default), the bootloader will permanently disable UART bootloader decryption access on first boot. If set, the UART bootloader will still be able to access hardware decryption.
|
||||
|
||||
Only set this option in testing environments. Setting this option allows complete bypass of flash encryption.
|
||||
|
||||
config FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_CACHE
|
||||
bool "Leave UART bootloader flash cache enabled"
|
||||
depends on FLASH_ENCRYPTION_INSECURE
|
||||
default N
|
||||
help
|
||||
If not set (default), the bootloader will permanently disable UART bootloader flash cache access on first boot. If set, the UART bootloader will still be able to access the flash cache.
|
||||
|
||||
Only set this option in testing environments.
|
||||
|
||||
config SECURE_BOOT_TEST_MODE
|
||||
bool "Secure boot test mode: don't permanently set any efuses"
|
||||
depends on SECURE_BOOT_INSECURE
|
||||
default N
|
||||
help
|
||||
If this option is set, all permanent secure boot changes (via Efuse) are disabled.
|
||||
|
||||
Log output will state changes which would be applied, but they will not be.
|
||||
|
||||
This option is for testing purposes only - it completely disables secure boot protection.
|
||||
|
||||
|
||||
endmenu # Potentially Insecure
|
||||
endmenu # Security features
|
||||
|
||||
@@ -1,67 +1,28 @@
|
||||
# This is for tracking the top level project path
|
||||
if(BOOTLOADER_BUILD)
|
||||
set(main_project_path "${CMAKE_BINARY_DIR}/../..")
|
||||
else()
|
||||
set(main_project_path "${IDF_PROJECT_PATH}")
|
||||
endif()
|
||||
|
||||
get_filename_component(secure_boot_signing_key
|
||||
"${CONFIG_SECURE_BOOT_SIGNING_KEY}"
|
||||
ABSOLUTE BASE_DIR "${main_project_path}")
|
||||
if(NOT EXISTS ${secure_boot_signing_key})
|
||||
# If the signing key is not found, create a phony gen_secure_boot_signing_key target that
|
||||
# fails the build. fail_at_build_time also touches CMakeCache.txt to cause a cmake run next time
|
||||
# (to pick up a new signing key if one exists, etc.)
|
||||
fail_at_build_time(gen_secure_boot_signing_key
|
||||
"Secure Boot Signing Key ${CONFIG_SECURE_BOOT_SIGNING_KEY} does not exist. Generate using:"
|
||||
"\tespsecure.py generate_signing_key ${CONFIG_SECURE_BOOT_SIGNING_KEY}")
|
||||
else()
|
||||
add_custom_target(gen_secure_boot_signing_key)
|
||||
endif()
|
||||
|
||||
if(BOOTLOADER_BUILD OR NOT IDF_BUILD_ARTIFACTS)
|
||||
return() # don't keep recursing, generate on project builds
|
||||
return() # don't keep recursing!
|
||||
endif()
|
||||
|
||||
# Glue to build the bootloader subproject binary as an external
|
||||
# cmake project under this one
|
||||
#
|
||||
#
|
||||
set(bootloader_build_dir "${IDF_BUILD_ARTIFACTS_DIR}/bootloader")
|
||||
set(bootloader_build_dir "${CMAKE_BINARY_DIR}/bootloader")
|
||||
set(bootloader_binary_files
|
||||
"${bootloader_build_dir}/bootloader.elf"
|
||||
"${bootloader_build_dir}/bootloader.bin"
|
||||
"${bootloader_build_dir}/bootloader.map"
|
||||
)
|
||||
|
||||
# These additional files may get generated
|
||||
if(CONFIG_SECURE_BOOTLOADER_REFLASHABLE)
|
||||
set(bootloader_binary_files
|
||||
${bootloader_binary_files}
|
||||
"${bootloader_build_dir}/bootloader-reflash-digest.bin"
|
||||
"${bootloader_build_dir}/secure-bootloader-key-192.bin"
|
||||
"${bootloader_build_dir}/secure-bootloader-key-256.bin"
|
||||
)
|
||||
endif()
|
||||
|
||||
if((NOT CONFIG_SECURE_BOOT_ENABLED) OR
|
||||
CONFIG_SECURE_BOOTLOADER_REFLASHABLE OR
|
||||
CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH)
|
||||
externalproject_add(bootloader
|
||||
# TODO: support overriding the bootloader in COMPONENT_PATHS
|
||||
SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/subproject"
|
||||
BINARY_DIR "${bootloader_build_dir}"
|
||||
CMAKE_ARGS -DSDKCONFIG=${SDKCONFIG} -DIDF_PATH=${IDF_PATH}
|
||||
-DSECURE_BOOT_SIGNING_KEY=${secure_boot_signing_key}
|
||||
-DEXTRA_COMPONENT_DIRS=${CMAKE_CURRENT_LIST_DIR}
|
||||
INSTALL_COMMAND ""
|
||||
BUILD_ALWAYS 1 # no easy way around this...
|
||||
BUILD_BYPRODUCTS ${bootloader_binary_files}
|
||||
DEPENDS gen_secure_boot_signing_key
|
||||
)
|
||||
else()
|
||||
fail_at_build_time(bootloader "Invalid bootloader target: bad sdkconfig?")
|
||||
endif()
|
||||
externalproject_add(bootloader
|
||||
# TODO: support overriding the bootloader in COMPONENT_PATHS
|
||||
SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/subproject"
|
||||
BINARY_DIR "${bootloader_build_dir}"
|
||||
CMAKE_ARGS -DSDKCONFIG=${SDKCONFIG} -DIDF_PATH=${IDF_PATH}
|
||||
-DEXTRA_COMPONENT_DIRS=${CMAKE_CURRENT_LIST_DIR}
|
||||
INSTALL_COMMAND ""
|
||||
BUILD_ALWAYS 1 # no easy way around this...
|
||||
BUILD_BYPRODUCTS ${bootloader_binary_files}
|
||||
)
|
||||
|
||||
# this is a hack due to an (annoying) shortcoming in cmake, it can't
|
||||
# extend the 'clean' target to the external project
|
||||
|
||||
@@ -10,7 +10,7 @@ if(NOT IDF_PATH)
|
||||
"in by the parent build process.")
|
||||
endif()
|
||||
|
||||
set(COMPONENTS bootloader esptool_py esp32 partition_table soc bootloader_support log spi_flash micro-ecc soc main efuse)
|
||||
set(COMPONENTS bootloader esptool_py esp32 partition_table soc bootloader_support log spi_flash micro-ecc soc main)
|
||||
set(BOOTLOADER_BUILD 1)
|
||||
add_definitions(-DBOOTLOADER_BUILD=1)
|
||||
|
||||
@@ -21,117 +21,8 @@ project(bootloader)
|
||||
|
||||
target_linker_script(bootloader.elf
|
||||
"main/esp32.bootloader.ld"
|
||||
"main/esp32.bootloader.rom.ld"
|
||||
)
|
||||
|
||||
# as cmake won't attach linker args to a header-only library, attach
|
||||
# linker args directly to the bootloader.elf
|
||||
set(ESP32_BOOTLOADER_LINKER_SCRIPTS
|
||||
"${IDF_PATH}/components/esp32/ld/esp32.rom.ld"
|
||||
"${IDF_PATH}/components/esp32/ld/esp32.rom.spiram_incompatible_fns.ld"
|
||||
"${IDF_PATH}/components/esp32/ld/esp32.peripherals.ld")
|
||||
|
||||
"main/esp32.bootloader.rom.ld")
|
||||
# Imported from esp32 component
|
||||
target_linker_script(bootloader.elf ${ESP32_BOOTLOADER_LINKER_SCRIPTS})
|
||||
|
||||
target_link_libraries(bootloader.elf gcc)
|
||||
|
||||
set(secure_boot_signing_key ${SECURE_BOOT_SIGNING_KEY})
|
||||
|
||||
string(REPLACE ";" " " espsecurepy "${ESPSECUREPY}")
|
||||
string(REPLACE ";" " " espefusepy "${ESPEFUSEPY}")
|
||||
set(esptoolpy_write_flash "${ESPTOOLPY_WRITE_FLASH_STR}")
|
||||
|
||||
if(CONFIG_SECURE_BOOTLOADER_REFLASHABLE)
|
||||
if(CONFIG_SECURE_BOOTLOADER_KEY_ENCODING_192BIT)
|
||||
set(key_digest_len 192)
|
||||
else()
|
||||
set(key_digest_len 256)
|
||||
endif()
|
||||
|
||||
get_filename_component(bootloader_digest_bin
|
||||
"bootloader-reflash-digest.bin"
|
||||
ABSOLUTE BASE_DIR "${CMAKE_BINARY_DIR}")
|
||||
|
||||
get_filename_component(secure_bootloader_key
|
||||
"secure-bootloader-key-${key_digest_len}.bin"
|
||||
ABSOLUTE BASE_DIR "${CMAKE_BINARY_DIR}")
|
||||
|
||||
add_custom_command(OUTPUT "${secure_bootloader_key}"
|
||||
COMMAND ${ESPSECUREPY} digest_private_key
|
||||
--keylen "${key_digest_len}"
|
||||
--keyfile "${secure_boot_signing_key}"
|
||||
"${secure_bootloader_key}"
|
||||
VERBATIM)
|
||||
|
||||
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
|
||||
add_custom_target(gen_secure_bootloader_key ALL DEPENDS "${secure_bootloader_key}")
|
||||
else()
|
||||
if(NOT EXISTS "${secure_bootloader_key}")
|
||||
message(FATAL_ERROR
|
||||
"No pre-generated key for a reflashable secure bootloader is available, "
|
||||
"due to signing configuration."
|
||||
"\nTo generate one, you can use this command:"
|
||||
"\n\t${espsecurepy} generate_flash_encryption_key ${secure_bootloader_key}"
|
||||
"\nIf a signing key is present, then instead use:"
|
||||
"\n\t${ESPSECUREPY} digest_private_key "
|
||||
"--keylen (192/256) --keyfile KEYFILE "
|
||||
"${secure_bootloader_key}")
|
||||
endif()
|
||||
add_custom_target(gen_secure_bootloader_key)
|
||||
endif()
|
||||
|
||||
add_custom_command(OUTPUT "${bootloader_digest_bin}"
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "DIGEST ${bootloader_digest_bin}"
|
||||
COMMAND ${ESPSECUREPY} digest_secure_bootloader --keyfile "${secure_bootloader_key}"
|
||||
-o "${bootloader_digest_bin}" "${CMAKE_BINARY_DIR}/bootloader.bin"
|
||||
DEPENDS gen_secure_bootloader_key "${CMAKE_BINARY_DIR}/bootloader.bin"
|
||||
VERBATIM)
|
||||
|
||||
add_custom_target (gen_bootloader_digest_bin ALL DEPENDS "${bootloader_digest_bin}")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SECURE_BOOTLOADER_ONE_TIME_FLASH)
|
||||
add_custom_command(TARGET bootloader POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
"=============================================================================="
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
"Bootloader built. Secure boot enabled, so bootloader not flashed automatically."
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
"One-time flash command is:"
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
"\t${esptoolpy_write_flash} ${BOOTLOADER_OFFSET} ${CMAKE_BINARY_DIR}/bootloader.bin"
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
"* IMPORTANT: After first boot, BOOTLOADER CANNOT BE RE-FLASHED on same device"
|
||||
VERBATIM)
|
||||
|
||||
elseif(CONFIG_SECURE_BOOTLOADER_REFLASHABLE)
|
||||
add_custom_command(TARGET bootloader POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
"=============================================================================="
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
"Bootloader built and secure digest generated."
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
"Secure boot enabled, so bootloader not flashed automatically."
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
"Burn secure boot key to efuse using:"
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
"\t${espefusepy} burn_key secure_boot ${secure_bootloader_key}"
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
"First time flash command is:"
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
"\t${esptoolpy_write_flash} ${BOOTLOADER_OFFSET} ${CMAKE_BINARY_DIR}/bootloader.bin"
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
"=============================================================================="
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
"To reflash the bootloader after initial flash:"
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
"\t${esptoolpy_write_flash} 0x0 ${bootloader_digest_bin}"
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
"=============================================================================="
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
"* After first boot, only re-flashes of this kind (with same key) will be accepted."
|
||||
COMMAND ${CMAKE_COMMAND} -E echo
|
||||
"* Not recommended to re-use the same secure boot keyfile on multiple production devices."
|
||||
DEPENDS gen_secure_bootloader_key gen_bootloader_digest_bin
|
||||
VERBATIM)
|
||||
endif()
|
||||
|
||||
@@ -8,7 +8,7 @@ endif
|
||||
|
||||
PROJECT_NAME := bootloader
|
||||
|
||||
COMPONENTS := esptool_py bootloader_support log spi_flash micro-ecc soc main efuse
|
||||
COMPONENTS := esptool_py bootloader_support log spi_flash micro-ecc soc main
|
||||
|
||||
# Clear C and CXX from top level project
|
||||
CFLAGS =
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "bootloader_common.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "rom/rtc.h"
|
||||
|
||||
static const char* TAG = "boot";
|
||||
|
||||
@@ -75,8 +74,7 @@ static int selected_boot_partition(const bootloader_state_t *bs)
|
||||
int boot_index = bootloader_utility_get_selected_boot_partition(bs);
|
||||
if (boot_index == INVALID_INDEX) {
|
||||
return boot_index; // Unrecoverable failure (not due to corrupt ota data or bad partition contents)
|
||||
}
|
||||
if (rtc_get_reset_reason(0) != DEEPSLEEP_RESET) {
|
||||
} else {
|
||||
// Factory firmware.
|
||||
#ifdef CONFIG_BOOTLOADER_FACTORY_RESET
|
||||
if (bootloader_common_check_long_hold_gpio(CONFIG_BOOTLOADER_NUM_PIN_FACTORY_RESET, CONFIG_BOOTLOADER_HOLD_TIME_GPIO) == 1) {
|
||||
|
||||
@@ -40,12 +40,12 @@ SECTIONS
|
||||
*(.iram1 .iram1.*) /* catch stray IRAM_ATTR */
|
||||
*liblog.a:(.literal .text .literal.* .text.*)
|
||||
*libgcc.a:(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_clock.*(.literal.esp_clk_apb_freq .text.esp_clk_apb_freq)
|
||||
*libbootloader_support.a:bootloader_common.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_flash.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_random.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_utility.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:bootloader_sha.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:efuse.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:esp_image_format.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_encrypt.*(.literal .text .literal.* .text.*)
|
||||
*libbootloader_support.a:flash_partitions.*(.literal .text .literal.* .text.*)
|
||||
@@ -53,9 +53,7 @@ SECTIONS
|
||||
*libbootloader_support.a:secure_boot_signatures.*(.literal .text .literal.* .text.*)
|
||||
*libmicro-ecc.a:*.*(.literal .text .literal.* .text.*)
|
||||
*libspi_flash.a:*.*(.literal .text .literal.* .text.*)
|
||||
*libsoc.a:rtc_clk.*(.literal.rtc_clk_apb_freq_get .text.rtc_clk_apb_freq_get)
|
||||
*libsoc.a:rtc_wdt.*(.literal .text .literal.* .text.*)
|
||||
*libefuse.a:*.*(.literal .text .literal.* .text.*)
|
||||
*(.fini.literal)
|
||||
*(.fini)
|
||||
*(.gnu.version)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
set(COMPONENT_SRCS "src/bootloader_clock.c"
|
||||
"src/bootloader_common.c"
|
||||
"src/bootloader_flash.c"
|
||||
"src/bootloader_flash_config.c"
|
||||
"src/bootloader_random.c"
|
||||
"src/bootloader_sha.c"
|
||||
"src/bootloader_utility.c"
|
||||
"src/efuse.c"
|
||||
"src/esp_image_format.c"
|
||||
"src/flash_encrypt.c"
|
||||
"src/flash_partitions.c"
|
||||
@@ -15,47 +15,13 @@ set(COMPONENT_SRCS "src/bootloader_clock.c"
|
||||
if(${BOOTLOADER_BUILD})
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "include include_bootloader")
|
||||
set(COMPONENT_REQUIRES)
|
||||
set(COMPONENT_PRIV_REQUIRES spi_flash micro-ecc efuse)
|
||||
set(COMPONENT_PRIV_REQUIRES spi_flash micro-ecc)
|
||||
list(APPEND COMPONENT_SRCS "src/bootloader_init.c")
|
||||
|
||||
if(CONFIG_SECURE_SIGNED_APPS)
|
||||
get_filename_component(secure_boot_verification_key
|
||||
"signature_verification_key.bin"
|
||||
ABSOLUTE BASE_DIR "${CMAKE_BINARY_DIR}")
|
||||
if(CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES)
|
||||
add_custom_command(OUTPUT "${secure_boot_verification_key}"
|
||||
COMMAND ${ESPSECUREPY}
|
||||
extract_public_key --keyfile "${secure_boot_signing_key}"
|
||||
"${secure_boot_verification_key}"
|
||||
DEPENDS gen_secure_boot_signing_key
|
||||
VERBATIM)
|
||||
else()
|
||||
get_filename_component(orig_secure_boot_verification_key
|
||||
"${CONFIG_SECURE_BOOT_VERIFICATION_KEY}"
|
||||
ABSOLUTE BASE_DIR "${main_project_path}")
|
||||
if(NOT EXISTS ${orig_secure_boot_verification_key})
|
||||
message(FATAL_ERROR
|
||||
"Secure Boot Verification Public Key ${CONFIG_SECURE_BOOT_VERIFICATION_KEY} does not exist."
|
||||
"\nThis can be extracted from the private signing key."
|
||||
"\nSee docs/security/secure-boot.rst for details.")
|
||||
endif()
|
||||
|
||||
add_custom_command(OUTPUT "${secure_boot_verification_key}"
|
||||
COMMAND ${CMAKE_COMMAND} -E copy "${orig_secure_boot_verification_key}"
|
||||
"${secure_boot_verification_key}"
|
||||
DEPENDS "${orig_secure_boot_verification_key}"
|
||||
VERBATIM)
|
||||
endif()
|
||||
set(COMPONENT_EMBED_FILES "${secure_boot_verification_key}")
|
||||
set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
|
||||
APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES
|
||||
"${secure_boot_verification_key}")
|
||||
endif()
|
||||
else()
|
||||
set(COMPONENT_ADD_INCLUDEDIRS "include")
|
||||
set(COMPONENT_PRIV_INCLUDEDIRS "include_bootloader")
|
||||
set(COMPONENT_REQUIRES)
|
||||
set(COMPONENT_PRIV_REQUIRES spi_flash mbedtls micro-ecc efuse)
|
||||
set(COMPONENT_PRIV_REQUIRES spi_flash mbedtls micro-ecc)
|
||||
endif()
|
||||
|
||||
register_component()
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
|
||||
#pragma once
|
||||
#include "esp_flash_data_types.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "esp_image_format.h"
|
||||
|
||||
/// Type of hold a GPIO in low state
|
||||
typedef enum {
|
||||
@@ -24,35 +22,22 @@ typedef enum {
|
||||
GPIO_NOT_HOLD = 0 /*!< If the GPIO input is not low */
|
||||
} esp_comm_gpio_hold_t;
|
||||
|
||||
typedef enum {
|
||||
ESP_IMAGE_BOOTLOADER,
|
||||
ESP_IMAGE_APPLICATION
|
||||
} esp_image_type;
|
||||
|
||||
/**
|
||||
* @brief Calculate crc for the OTA data select.
|
||||
* @brief Calculate crc for the OTA data partition.
|
||||
*
|
||||
* @param[in] s The OTA data select.
|
||||
* @param[in] ota_data The OTA data partition.
|
||||
* @return Returns crc value.
|
||||
*/
|
||||
uint32_t bootloader_common_ota_select_crc(const esp_ota_select_entry_t *s);
|
||||
|
||||
/**
|
||||
* @brief Verifies the validity of the OTA data select
|
||||
* @brief Verifies the validity of the OTA data partition
|
||||
*
|
||||
* @param[in] s The OTA data select.
|
||||
* @param[in] ota_data The OTA data partition.
|
||||
* @return Returns true on valid, false otherwise.
|
||||
*/
|
||||
bool bootloader_common_ota_select_valid(const esp_ota_select_entry_t *s);
|
||||
|
||||
/**
|
||||
* @brief Returns true if OTADATA is not marked as bootable partition.
|
||||
*
|
||||
* @param[in] s The OTA data select.
|
||||
* @return Returns true if OTADATA invalid, false otherwise.
|
||||
*/
|
||||
bool bootloader_common_ota_select_invalid(const esp_ota_select_entry_t *s);
|
||||
|
||||
/**
|
||||
* @brief Check if the GPIO input is a long hold or a short hold.
|
||||
*
|
||||
@@ -106,62 +91,3 @@ bool bootloader_common_label_search(const char *list, char *label);
|
||||
* - ESP_FAIL: An allocation error occurred.
|
||||
*/
|
||||
esp_err_t bootloader_common_get_sha256_of_partition(uint32_t address, uint32_t size, int type, uint8_t *out_sha_256);
|
||||
|
||||
/**
|
||||
* @brief Returns the number of active otadata.
|
||||
*
|
||||
* @param[in] two_otadata Pointer on array from two otadata structures.
|
||||
*
|
||||
* @return The number of active otadata (0 or 1).
|
||||
* - -1: If it does not have active otadata.
|
||||
*/
|
||||
int bootloader_common_get_active_otadata(esp_ota_select_entry_t *two_otadata);
|
||||
|
||||
/**
|
||||
* @brief Returns the number of active otadata.
|
||||
*
|
||||
* @param[in] two_otadata Pointer on array from two otadata structures.
|
||||
* @param[in] valid_two_otadata Pointer on array from two bools. True means select.
|
||||
* @param[in] max True - will select the maximum ota_seq number, otherwise the minimum.
|
||||
*
|
||||
* @return The number of active otadata (0 or 1).
|
||||
* - -1: If it does not have active otadata.
|
||||
*/
|
||||
int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata, bool *valid_two_otadata, bool max);
|
||||
|
||||
/**
|
||||
* @brief Returns esp_app_desc structure for app partition. This structure includes app version.
|
||||
*
|
||||
* Returns a description for the requested app partition.
|
||||
* @param[in] partition App partition description.
|
||||
* @param[out] app_desc Structure of info about app.
|
||||
* @return
|
||||
* - ESP_OK: Successful.
|
||||
* - ESP_ERR_INVALID_ARG: The arguments passed are not valid.
|
||||
* - ESP_ERR_NOT_FOUND: app_desc structure is not found. Magic word is incorrect.
|
||||
* - ESP_FAIL: mapping is fail.
|
||||
*/
|
||||
esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc);
|
||||
|
||||
/**
|
||||
* @brief Get chip revision
|
||||
*
|
||||
* @return Chip revision number
|
||||
*/
|
||||
uint8_t bootloader_common_get_chip_revision(void);
|
||||
|
||||
/**
|
||||
* @brief Check if the image (bootloader and application) has valid chip ID and revision
|
||||
*
|
||||
* @param[in] img_hdr: image header
|
||||
* @param[in] type: image type, bootloader or application
|
||||
* @return
|
||||
* - ESP_OK: image and chip are matched well
|
||||
* - ESP_FAIL: image doesn't match to the chip
|
||||
*/
|
||||
esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hdr, esp_image_type type);
|
||||
|
||||
/**
|
||||
* @brief Configure VDDSDIO, call this API to rise VDDSDIO to 1.9V when VDDSDIO regulator is enabled as 1.8V mode.
|
||||
*/
|
||||
void bootloader_common_vddsdio_configure();
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "esp_image_format.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Update the flash id in g_rom_flashchip(global esp_rom_spiflash_chip_t structure).
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void bootloader_flash_update_id();
|
||||
|
||||
/**
|
||||
* @brief Set the flash CS setup and hold time.
|
||||
*
|
||||
* @note CS setup time is recomemded to be 1.5T, and CS hold time is recommended to be 2.5T.
|
||||
* cs_setup = 1, cs_setup_time = 0; cs_hold = 1, cs_hold_time = 1.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void bootloader_flash_cs_timing_config();
|
||||
|
||||
/**
|
||||
* @brief Configure SPI flash clock.
|
||||
*
|
||||
* @note This function only set clock frequency for SPI0.
|
||||
*
|
||||
* @param pfhdr Pointer to App image header, from where to fetch flash settings.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void bootloader_flash_clock_config(const esp_image_header_t* pfhdr);
|
||||
|
||||
/**
|
||||
* @brief Configure SPI flash gpio, include the IO matrix and drive strength configuration.
|
||||
*
|
||||
* @param pfhdr Pointer to App image header, from where to fetch flash settings.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void bootloader_flash_gpio_config(const esp_image_header_t* pfhdr);
|
||||
|
||||
/**
|
||||
* @brief Configure SPI flash read dummy based on different mode and frequency.
|
||||
*
|
||||
* @param pfhdr Pointer to App image header, from where to fetch flash settings.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void bootloader_flash_dummy_config(const esp_image_header_t* pfhdr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
99
components/bootloader_support/include/esp_efuse.h
Normal file
99
components/bootloader_support/include/esp_efuse.h
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#ifndef _ESP_EFUSE_H
|
||||
#define _ESP_EFUSE_H
|
||||
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* @brief Permanently update values written to the efuse write registers
|
||||
*
|
||||
* After updating EFUSE_BLKx_WDATAx_REG registers with new values to
|
||||
* write, call this function to permanently write them to efuse.
|
||||
*
|
||||
* @note Setting bits in efuse is permanent, they cannot be unset.
|
||||
*
|
||||
* @note Due to this restriction you don't need to copy values to
|
||||
* Efuse write registers from the matching read registers, bits which
|
||||
* are set in the read register but unset in the matching write
|
||||
* register will be unchanged when new values are burned.
|
||||
*
|
||||
* @note This function is not threadsafe, if calling code updates
|
||||
* efuse values from multiple tasks then this is caller's
|
||||
* responsibility to serialise.
|
||||
*
|
||||
* After burning new efuses, the read registers are updated to match
|
||||
* the new efuse values.
|
||||
*/
|
||||
void esp_efuse_burn_new_values(void);
|
||||
|
||||
/* @brief Reset efuse write registers
|
||||
*
|
||||
* Efuse write registers are written to zero, to negate
|
||||
* any changes that have been staged here.
|
||||
*/
|
||||
void esp_efuse_reset(void);
|
||||
|
||||
/* @brief Disable BASIC ROM Console via efuse
|
||||
*
|
||||
* By default, if booting from flash fails the ESP32 will boot a
|
||||
* BASIC console in ROM.
|
||||
*
|
||||
* Call this function (from bootloader or app) to permanently
|
||||
* disable the console on this chip.
|
||||
*/
|
||||
void esp_efuse_disable_basic_rom_console(void);
|
||||
|
||||
/* @brief Encode one or more sets of 6 byte sequences into
|
||||
* 8 bytes suitable for 3/4 Coding Scheme.
|
||||
*
|
||||
* This function is only useful if the CODING_SCHEME efuse
|
||||
* is set to value 1 for 3/4 Coding Scheme.
|
||||
*
|
||||
* @param[in] in_bytes Pointer to a sequence of bytes to encode for 3/4 Coding Scheme. Must have length in_bytes_len. After being written to hardware, these bytes will read back as little-endian words.
|
||||
* @param[out] out_words Pointer to array of words suitable for writing to efuse write registers. Array must contain 2 words (8 bytes) for every 6 bytes in in_bytes_len. Can be a pointer to efuse write registers.
|
||||
* @param in_bytes_len. Length of array pointed to by in_bytes, in bytes. Must be a multiple of 6.
|
||||
*
|
||||
* @return ESP_ERR_INVALID_ARG if either pointer is null or in_bytes_len is not a multiple of 6. ESP_OK otherwise.
|
||||
*/
|
||||
esp_err_t esp_efuse_apply_34_encoding(const uint8_t *in_bytes, uint32_t *out_words, size_t in_bytes_len);
|
||||
|
||||
/* @brief Write random data to efuse key block write registers
|
||||
*
|
||||
* @note Caller is responsible for ensuring efuse
|
||||
* block is empty and not write protected, before calling.
|
||||
*
|
||||
* @note Behaviour depends on coding scheme: a 256-bit key is
|
||||
* generated and written for Coding Scheme "None", a 192-bit key
|
||||
* is generated, extended to 256-bits by the Coding Scheme,
|
||||
* and then writtten for 3/4 Coding Scheme.
|
||||
*
|
||||
* @note This function does not burn the new values, caller should
|
||||
* call esp_efuse_burn_new_values() when ready to do this.
|
||||
*
|
||||
* @param blk_wdata0_reg Address of the first data write register
|
||||
* in the block
|
||||
*/
|
||||
void esp_efuse_write_random_key(uint32_t blk_wdata0_reg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_EFUSE_H */
|
||||
|
||||
@@ -55,19 +55,6 @@ typedef enum {
|
||||
|
||||
#define ESP_IMAGE_HEADER_MAGIC 0xE9
|
||||
|
||||
/**
|
||||
* @brief ESP chip ID
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
ESP_CHIP_ID_ESP32 = 0x0000, /*!< chip ID: ESP32 */
|
||||
ESP_CHIP_ID_INVALID = 0xFFFF /*!< Invalid chip ID (we defined it to make sure the esp_chip_id_t is 2 bytes size) */
|
||||
} __attribute__((packed)) esp_chip_id_t;
|
||||
|
||||
/** @cond */
|
||||
_Static_assert(sizeof(esp_chip_id_t) == 2, "esp_chip_id_t should be 16 bit");
|
||||
/** @endcond */
|
||||
|
||||
/* Main header of binary image */
|
||||
typedef struct {
|
||||
uint8_t magic;
|
||||
@@ -84,9 +71,8 @@ typedef struct {
|
||||
uint8_t wp_pin;
|
||||
/* Drive settings for the SPI flash pins (read by ROM bootloader) */
|
||||
uint8_t spi_pin_drv[3];
|
||||
esp_chip_id_t chip_id; /*!< Chip identification number */
|
||||
uint8_t min_chip_rev; /*!< Minimum chip revision supported by image */
|
||||
uint8_t reserved[8]; /*!< Reserved bytes in additional header space, currently unused */
|
||||
/* Reserved bytes in ESP32 additional header space, currently unused */
|
||||
uint8_t reserved[11];
|
||||
/* If 1, a SHA256 digest "simple hash" (of the entire image) is appended after the checksum. Included in image length. This digest
|
||||
* is separate to secure boot and only used for detecting corruption. For secure boot signed images, the signature
|
||||
* is appended after this (and the simple hash is included in the signed data). */
|
||||
@@ -103,25 +89,6 @@ typedef struct {
|
||||
uint32_t data_len;
|
||||
} esp_image_segment_header_t;
|
||||
|
||||
#define ESP_APP_DESC_MAGIC_WORD 0xABCD5432 /*!< The magic word for the esp_app_desc structure that is in DROM. */
|
||||
|
||||
/**
|
||||
* @brief Description about application.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t magic_word; /*!< Magic word ESP_APP_DESC_MAGIC_WORD */
|
||||
uint32_t secure_version; /*!< Secure version */
|
||||
uint32_t reserv1[2]; /*!< --- */
|
||||
char version[32]; /*!< Application version */
|
||||
char project_name[32]; /*!< Project name */
|
||||
char time[16]; /*!< Compile time */
|
||||
char date[16]; /*!< Compile date*/
|
||||
char idf_ver[32]; /*!< Version IDF */
|
||||
uint8_t app_elf_sha256[32]; /*!< sha256 of elf file */
|
||||
uint32_t reserv2[20]; /*!< --- */
|
||||
} esp_app_desc_t;
|
||||
_Static_assert(sizeof(esp_app_desc_t) == 256, "esp_app_desc_t should be 256 bytes");
|
||||
|
||||
#define ESP_IMAGE_MAX_SEGMENTS 16
|
||||
|
||||
/* Structure to hold on-flash image metadata */
|
||||
|
||||
@@ -46,25 +46,6 @@ static inline bool esp_secure_boot_enabled(void) {
|
||||
return REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_RD_ABS_DONE_0;
|
||||
}
|
||||
|
||||
/** @brief Generate secure digest from bootloader image
|
||||
*
|
||||
* @important This function is intended to be called from bootloader code only.
|
||||
*
|
||||
* If secure boot is not yet enabled for bootloader, this will:
|
||||
* 1) generate the secure boot key and burn it on EFUSE
|
||||
* (without enabling R/W protection)
|
||||
* 2) generate the digest from bootloader and save it
|
||||
* to flash address 0x0
|
||||
*
|
||||
* If first boot gets interrupted after calling this function
|
||||
* but before esp_secure_boot_permanently_enable() is called, then
|
||||
* the key burned on EFUSE will not be regenerated, unless manually
|
||||
* done using espefuse.py tool
|
||||
*
|
||||
* @return ESP_OK if secure boot digest is generated
|
||||
* successfully or found to be already present
|
||||
*/
|
||||
esp_err_t esp_secure_boot_generate_digest(void);
|
||||
|
||||
/** @brief Enable secure boot if it is not already enabled.
|
||||
*
|
||||
@@ -73,13 +54,9 @@ esp_err_t esp_secure_boot_generate_digest(void);
|
||||
*
|
||||
* @important This function is intended to be called from bootloader code only.
|
||||
*
|
||||
* @important This will enable r/w protection of secure boot key on EFUSE,
|
||||
* therefore it is to be ensured that esp_secure_boot_generate_digest()
|
||||
* is called before this
|
||||
*
|
||||
* If secure boot is not yet enabled for bootloader, this will
|
||||
* 1) enable R/W protection of secure boot key on EFUSE
|
||||
* 2) enable secure boot by blowing the EFUSE_RD_ABS_DONE_0 efuse.
|
||||
* 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.)
|
||||
@@ -87,6 +64,7 @@ esp_err_t esp_secure_boot_generate_digest(void);
|
||||
* Will fail if efuses have been part-burned in a way that indicates
|
||||
* secure boot should not or could not be correctly enabled.
|
||||
*
|
||||
*
|
||||
* @return ESP_ERR_INVALID_STATE if efuse state doesn't allow
|
||||
* secure boot to be enabled cleanly. ESP_OK if secure boot
|
||||
* is enabled on this chip from now on.
|
||||
|
||||
@@ -30,13 +30,6 @@
|
||||
bootloader_support components only.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Get number of free pages
|
||||
*
|
||||
* @return Number of free pages
|
||||
*/
|
||||
uint32_t bootloader_mmap_get_free_pages();
|
||||
|
||||
/**
|
||||
* @brief Map a region of flash to data memory
|
||||
*
|
||||
|
||||
@@ -59,12 +59,3 @@ void bootloader_clock_configure()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
|
||||
int esp_clk_apb_freq(void)
|
||||
{
|
||||
return rtc_clk_apb_freq_get();
|
||||
}
|
||||
|
||||
#endif // BOOTLOADER_BUILD
|
||||
|
||||
@@ -27,14 +27,8 @@
|
||||
#include "bootloader_flash.h"
|
||||
#include "bootloader_common.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/rtc.h"
|
||||
#include "soc/spi_reg.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/apb_ctrl_reg.h"
|
||||
#include "esp_image_format.h"
|
||||
#include "bootloader_sha.h"
|
||||
#include "sys/param.h"
|
||||
|
||||
#define ESP_PARTITION_HASH_LEN 32 /* SHA-256 digest length */
|
||||
|
||||
@@ -45,14 +39,9 @@ uint32_t bootloader_common_ota_select_crc(const esp_ota_select_entry_t *s)
|
||||
return crc32_le(UINT32_MAX, (uint8_t*)&s->ota_seq, 4);
|
||||
}
|
||||
|
||||
bool bootloader_common_ota_select_invalid(const esp_ota_select_entry_t *s)
|
||||
{
|
||||
return s->ota_seq == UINT32_MAX || s->ota_state == ESP_OTA_IMG_INVALID || s->ota_state == ESP_OTA_IMG_ABORTED;
|
||||
}
|
||||
|
||||
bool bootloader_common_ota_select_valid(const esp_ota_select_entry_t *s)
|
||||
{
|
||||
return bootloader_common_ota_select_invalid(s) == false && s->crc == bootloader_common_ota_select_crc(s);
|
||||
return s->ota_seq != UINT32_MAX && s->crc == bootloader_common_ota_select_crc(s);
|
||||
}
|
||||
|
||||
esp_comm_gpio_hold_t bootloader_common_check_long_hold_gpio(uint32_t num_pin, uint32_t delay_sec)
|
||||
@@ -203,125 +192,3 @@ esp_err_t bootloader_common_get_sha256_of_partition (uint32_t address, uint32_t
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata, bool *valid_two_otadata, bool max)
|
||||
{
|
||||
if (two_otadata == NULL || valid_two_otadata == NULL) {
|
||||
return -1;
|
||||
}
|
||||
int active_otadata = -1;
|
||||
if (valid_two_otadata[0] && valid_two_otadata[1]) {
|
||||
int condition = (max == true) ? MAX(two_otadata[0].ota_seq, two_otadata[1].ota_seq) : MIN(two_otadata[0].ota_seq, two_otadata[1].ota_seq);
|
||||
if (condition == two_otadata[0].ota_seq) {
|
||||
active_otadata = 0;
|
||||
} else {
|
||||
active_otadata = 1;
|
||||
}
|
||||
ESP_LOGD(TAG, "Both OTA copies are valid");
|
||||
} else {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (valid_two_otadata[i]) {
|
||||
active_otadata = i;
|
||||
ESP_LOGD(TAG, "Only otadata[%d] is valid", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return active_otadata;
|
||||
}
|
||||
|
||||
int bootloader_common_get_active_otadata(esp_ota_select_entry_t *two_otadata)
|
||||
{
|
||||
if (two_otadata == NULL) {
|
||||
return -1;
|
||||
}
|
||||
bool valid_two_otadata[2];
|
||||
valid_two_otadata[0] = bootloader_common_ota_select_valid(&two_otadata[0]);
|
||||
valid_two_otadata[1] = bootloader_common_ota_select_valid(&two_otadata[1]);
|
||||
return bootloader_common_select_otadata(two_otadata, valid_two_otadata, true);
|
||||
}
|
||||
|
||||
esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc)
|
||||
{
|
||||
if (partition == NULL || app_desc == NULL || partition->offset == 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
const uint8_t *image = bootloader_mmap(partition->offset, partition->size);
|
||||
if (image == NULL) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", partition->offset, partition->size);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
memcpy(app_desc, image + sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t), sizeof(esp_app_desc_t));
|
||||
bootloader_munmap(image);
|
||||
|
||||
if (app_desc->magic_word != ESP_APP_DESC_MAGIC_WORD) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void bootloader_common_vddsdio_configure()
|
||||
{
|
||||
#if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V
|
||||
rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
|
||||
if (cfg.enable == 1 && cfg.tieh == RTC_VDDSDIO_TIEH_1_8V) { // VDDSDIO regulator is enabled @ 1.8V
|
||||
cfg.drefh = 3;
|
||||
cfg.drefm = 3;
|
||||
cfg.drefl = 3;
|
||||
cfg.force = 1;
|
||||
rtc_vddsdio_set_config(cfg);
|
||||
ets_delay_us(10); // wait for regulator to become stable
|
||||
}
|
||||
#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32
|
||||
uint8_t bootloader_common_get_chip_revision(void)
|
||||
{
|
||||
uint8_t eco_bit0, eco_bit1, eco_bit2;
|
||||
eco_bit0 = (REG_READ(EFUSE_BLK0_RDATA3_REG) & 0xF000) >> 15;
|
||||
eco_bit1 = (REG_READ(EFUSE_BLK0_RDATA5_REG) & 0x100000) >> 20;
|
||||
eco_bit2 = (REG_READ(APB_CTRL_DATE_REG) & 0x80000000) >> 31;
|
||||
uint32_t combine_value = (eco_bit2 << 2) | (eco_bit1 << 1) | eco_bit0;
|
||||
uint8_t chip_ver = 0;
|
||||
switch (combine_value) {
|
||||
case 0:
|
||||
chip_ver = 0;
|
||||
break;
|
||||
case 1:
|
||||
chip_ver = 1;
|
||||
break;
|
||||
case 3:
|
||||
chip_ver = 2;
|
||||
break;
|
||||
case 7:
|
||||
chip_ver = 3;
|
||||
break;
|
||||
default:
|
||||
chip_ver = 0;
|
||||
break;
|
||||
}
|
||||
return chip_ver;
|
||||
}
|
||||
#endif
|
||||
|
||||
esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hdr, esp_image_type type)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
esp_chip_id_t chip_id = CONFIG_IDF_FIRMWARE_CHIP_ID;
|
||||
if (chip_id != img_hdr->chip_id) {
|
||||
ESP_LOGE(TAG, "mismatch chip ID, expected %d, found %d", chip_id, img_hdr->chip_id);
|
||||
err = ESP_FAIL;
|
||||
}
|
||||
uint8_t revision = bootloader_common_get_chip_revision();
|
||||
if (revision < img_hdr->min_chip_rev) {
|
||||
ESP_LOGE(TAG, "can't run on lower chip revision, expected %d, found %d", revision, img_hdr->min_chip_rev);
|
||||
err = ESP_FAIL;
|
||||
} else if (revision != img_hdr->min_chip_rev) {
|
||||
ESP_LOGI(TAG, "chip revision: %d, min. %s chip revision: %d", revision, type == ESP_IMAGE_BOOTLOADER ? "bootloader" : "application", img_hdr->min_chip_rev);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -25,11 +25,6 @@ static const char *TAG = "bootloader_mmap";
|
||||
|
||||
static spi_flash_mmap_handle_t map;
|
||||
|
||||
uint32_t bootloader_mmap_get_free_pages()
|
||||
{
|
||||
return spi_flash_mmap_get_free_pages(SPI_FLASH_MMAP_DATA);
|
||||
}
|
||||
|
||||
const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
|
||||
{
|
||||
if (map) {
|
||||
@@ -96,22 +91,12 @@ static const char *TAG = "bootloader_flash";
|
||||
*/
|
||||
#define MMU_BLOCK0_VADDR 0x3f400000
|
||||
#define MMU_BLOCK50_VADDR 0x3f720000
|
||||
#define MMU_FREE_PAGES ((MMU_BLOCK50_VADDR - MMU_BLOCK0_VADDR) / FLASH_BLOCK_SIZE)
|
||||
|
||||
static bool mapped;
|
||||
|
||||
// Current bootloader mapping (ab)used for bootloader_read()
|
||||
static uint32_t current_read_mapping = UINT32_MAX;
|
||||
|
||||
uint32_t bootloader_mmap_get_free_pages()
|
||||
{
|
||||
/**
|
||||
* Allow mapping up to 50 of the 51 available MMU blocks (last one used for reads)
|
||||
* Since, bootloader_mmap function below assumes it to be 0x320000 (50 pages), we can safely do this.
|
||||
*/
|
||||
return MMU_FREE_PAGES;
|
||||
}
|
||||
|
||||
const void *bootloader_mmap(uint32_t src_addr, uint32_t size)
|
||||
{
|
||||
if (mapped) {
|
||||
|
||||
@@ -1,166 +0,0 @@
|
||||
// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include "string.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "rom/gpio.h"
|
||||
#include "rom/spi_flash.h"
|
||||
#include "rom/efuse.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "soc/spi_reg.h"
|
||||
#include "soc/spi_pins.h"
|
||||
#include "flash_qio_mode.h"
|
||||
#include "bootloader_flash_config.h"
|
||||
|
||||
void bootloader_flash_update_id()
|
||||
{
|
||||
g_rom_flashchip.device_id = bootloader_read_flash_id();
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_flash_cs_timing_config()
|
||||
{
|
||||
SET_PERI_REG_MASK(SPI_USER_REG(0), SPI_CS_HOLD_M | SPI_CS_SETUP_M);
|
||||
SET_PERI_REG_BITS(SPI_CTRL2_REG(0), SPI_HOLD_TIME_V, 1, SPI_HOLD_TIME_S);
|
||||
SET_PERI_REG_BITS(SPI_CTRL2_REG(0), SPI_SETUP_TIME_V, 0, SPI_SETUP_TIME_S);
|
||||
SET_PERI_REG_MASK(SPI_USER_REG(1), SPI_CS_HOLD_M | SPI_CS_SETUP_M);
|
||||
SET_PERI_REG_BITS(SPI_CTRL2_REG(1), SPI_HOLD_TIME_V, 1, SPI_HOLD_TIME_S);
|
||||
SET_PERI_REG_BITS(SPI_CTRL2_REG(1), SPI_SETUP_TIME_V, 0, SPI_SETUP_TIME_S);
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_flash_clock_config(const esp_image_header_t* pfhdr)
|
||||
{
|
||||
uint32_t spi_clk_div = 0;
|
||||
switch (pfhdr->spi_speed) {
|
||||
case ESP_IMAGE_SPI_SPEED_80M:
|
||||
spi_clk_div = 1;
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_40M:
|
||||
spi_clk_div = 2;
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_26M:
|
||||
spi_clk_div = 3;
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_20M:
|
||||
spi_clk_div = 4;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
esp_rom_spiflash_config_clk(spi_clk_div, 0);
|
||||
esp_rom_spiflash_config_clk(spi_clk_div, 1);
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_flash_gpio_config(const esp_image_header_t* pfhdr)
|
||||
{
|
||||
uint32_t drv = 2;
|
||||
if (pfhdr->spi_speed == ESP_IMAGE_SPI_SPEED_80M) {
|
||||
drv = 3;
|
||||
}
|
||||
|
||||
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
|
||||
uint32_t pkg_ver = chip_ver & 0x7;
|
||||
|
||||
if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) {
|
||||
// For ESP32D2WD the SPI pins are already configured
|
||||
// flash clock signal should come from IO MUX.
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) {
|
||||
// For ESP32PICOD2 the SPI pins are already configured
|
||||
// flash clock signal should come from IO MUX.
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) {
|
||||
// For ESP32PICOD4 the SPI pins are already configured
|
||||
// flash clock signal should come from IO MUX.
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
} else {
|
||||
const uint32_t spiconfig = ets_efuse_get_spiconfig();
|
||||
if (spiconfig == EFUSE_SPICONFIG_SPI_DEFAULTS) {
|
||||
gpio_matrix_out(SPI_IOMUX_PIN_NUM_CS, SPICS0_OUT_IDX, 0, 0);
|
||||
gpio_matrix_out(SPI_IOMUX_PIN_NUM_MISO, SPIQ_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(SPI_IOMUX_PIN_NUM_MISO, SPIQ_IN_IDX, 0);
|
||||
gpio_matrix_out(SPI_IOMUX_PIN_NUM_MOSI, SPID_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(SPI_IOMUX_PIN_NUM_MOSI, SPID_IN_IDX, 0);
|
||||
gpio_matrix_out(SPI_IOMUX_PIN_NUM_WP, SPIWP_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(SPI_IOMUX_PIN_NUM_WP, SPIWP_IN_IDX, 0);
|
||||
gpio_matrix_out(SPI_IOMUX_PIN_NUM_HD, SPIHD_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(SPI_IOMUX_PIN_NUM_HD, SPIHD_IN_IDX, 0);
|
||||
//select pin function gpio
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO);
|
||||
// flash clock signal should come from IO MUX.
|
||||
// set drive ability for clock
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
|
||||
uint32_t flash_id = g_rom_flashchip.device_id;
|
||||
if (flash_id == FLASH_ID_GD25LQ32C) {
|
||||
// Set drive ability for 1.8v flash in 80Mhz.
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA0_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA1_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA2_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA3_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CMD_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IRAM_ATTR bootloader_flash_dummy_config(const esp_image_header_t* pfhdr)
|
||||
{
|
||||
int spi_cache_dummy = 0;
|
||||
uint32_t modebit = READ_PERI_REG(SPI_CTRL_REG(0));
|
||||
if (modebit & SPI_FASTRD_MODE) {
|
||||
if (modebit & SPI_FREAD_QIO) { //SPI mode is QIO
|
||||
spi_cache_dummy = SPI0_R_QIO_DUMMY_CYCLELEN;
|
||||
} else if (modebit & SPI_FREAD_DIO) { //SPI mode is DIO
|
||||
spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN;
|
||||
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_ADDR_BITLEN_V, SPI0_R_DIO_ADDR_BITSLEN, SPI_USR_ADDR_BITLEN_S);
|
||||
} else if(modebit & (SPI_FREAD_QUAD | SPI_FREAD_DUAL)) { //SPI mode is QOUT or DIO
|
||||
spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN;
|
||||
}
|
||||
}
|
||||
|
||||
extern uint8_t g_rom_spiflash_dummy_len_plus[];
|
||||
switch (pfhdr->spi_speed) {
|
||||
case ESP_IMAGE_SPI_SPEED_80M:
|
||||
g_rom_spiflash_dummy_len_plus[0] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_80M;
|
||||
g_rom_spiflash_dummy_len_plus[1] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_80M;
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_40M:
|
||||
g_rom_spiflash_dummy_len_plus[0] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_40M;
|
||||
g_rom_spiflash_dummy_len_plus[1] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_40M;
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_26M:
|
||||
case ESP_IMAGE_SPI_SPEED_20M:
|
||||
g_rom_spiflash_dummy_len_plus[0] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_20M;
|
||||
g_rom_spiflash_dummy_len_plus[1] = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_20M;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + g_rom_spiflash_dummy_len_plus[0],
|
||||
SPI_USR_DUMMY_CYCLELEN_S);
|
||||
}
|
||||
@@ -48,8 +48,6 @@
|
||||
#include "bootloader_random.h"
|
||||
#include "bootloader_config.h"
|
||||
#include "bootloader_clock.h"
|
||||
#include "bootloader_common.h"
|
||||
#include "bootloader_flash_config.h"
|
||||
|
||||
#include "flash_qio_mode.h"
|
||||
|
||||
@@ -63,7 +61,8 @@ static const char* TAG = "boot";
|
||||
static esp_err_t bootloader_main();
|
||||
static void print_flash_info(const esp_image_header_t* pfhdr);
|
||||
static void update_flash_config(const esp_image_header_t* pfhdr);
|
||||
static void bootloader_init_flash_configure(const esp_image_header_t* pfhdr);
|
||||
static void vddsdio_configure();
|
||||
static void flash_gpio_configure(const esp_image_header_t* pfhdr);
|
||||
static void uart_console_configure(void);
|
||||
static void wdt_reset_check(void);
|
||||
|
||||
@@ -118,7 +117,7 @@ esp_err_t bootloader_init()
|
||||
|
||||
static esp_err_t bootloader_main()
|
||||
{
|
||||
bootloader_common_vddsdio_configure();
|
||||
vddsdio_configure();
|
||||
/* Read and keep flash ID, for further use. */
|
||||
g_rom_flashchip.device_id = bootloader_read_flash_id();
|
||||
esp_image_header_t fhdr;
|
||||
@@ -126,15 +125,7 @@ static esp_err_t bootloader_main()
|
||||
ESP_LOGE(TAG, "failed to load bootloader header!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
/* Check chip ID and minimum chip revision that supported by this image */
|
||||
uint8_t revision = bootloader_common_get_chip_revision();
|
||||
ESP_LOGI(TAG, "Chip Revision: %d", revision);
|
||||
if (bootloader_common_check_chip_validity(&fhdr, ESP_IMAGE_BOOTLOADER) != ESP_OK) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
bootloader_init_flash_configure(&fhdr);
|
||||
flash_gpio_configure(&fhdr);
|
||||
#if (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ == 240)
|
||||
//Check if ESP32 is rated for a CPU frequency of 160MHz only
|
||||
if (REG_GET_BIT(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_CPU_FREQ_RATED) &&
|
||||
@@ -294,15 +285,128 @@ static void print_flash_info(const esp_image_header_t* phdr)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void vddsdio_configure()
|
||||
{
|
||||
#if CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V
|
||||
rtc_vddsdio_config_t cfg = rtc_vddsdio_get_config();
|
||||
if (cfg.enable == 1 && cfg.tieh == RTC_VDDSDIO_TIEH_1_8V) { // VDDSDIO regulator is enabled @ 1.8V
|
||||
cfg.drefh = 3;
|
||||
cfg.drefm = 3;
|
||||
cfg.drefl = 3;
|
||||
cfg.force = 1;
|
||||
rtc_vddsdio_set_config(cfg);
|
||||
ets_delay_us(10); // wait for regulator to become stable
|
||||
}
|
||||
#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST
|
||||
}
|
||||
|
||||
#define FLASH_CLK_IO 6
|
||||
#define FLASH_CS_IO 11
|
||||
#define FLASH_SPIQ_IO 7
|
||||
#define FLASH_SPID_IO 8
|
||||
#define FLASH_SPIWP_IO 10
|
||||
#define FLASH_SPIHD_IO 9
|
||||
#define FLASH_IO_MATRIX_DUMMY_40M 1
|
||||
#define FLASH_IO_MATRIX_DUMMY_80M 2
|
||||
#define FLASH_IO_DRIVE_GD_WITH_1V8PSRAM 3
|
||||
|
||||
/*
|
||||
* Bootloader reads SPI configuration from bin header, so that
|
||||
* the burning configuration can be different with compiling configuration.
|
||||
*/
|
||||
static void IRAM_ATTR bootloader_init_flash_configure(const esp_image_header_t* pfhdr)
|
||||
static void IRAM_ATTR flash_gpio_configure(const esp_image_header_t* pfhdr)
|
||||
{
|
||||
bootloader_flash_gpio_config(pfhdr);
|
||||
bootloader_flash_dummy_config(pfhdr);
|
||||
bootloader_flash_cs_timing_config();
|
||||
int spi_cache_dummy = 0;
|
||||
int drv = 2;
|
||||
switch (pfhdr->spi_mode) {
|
||||
case ESP_IMAGE_SPI_MODE_QIO:
|
||||
spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN;
|
||||
break;
|
||||
case ESP_IMAGE_SPI_MODE_DIO:
|
||||
spi_cache_dummy = SPI0_R_DIO_DUMMY_CYCLELEN; //qio 3
|
||||
break;
|
||||
case ESP_IMAGE_SPI_MODE_QOUT:
|
||||
case ESP_IMAGE_SPI_MODE_DOUT:
|
||||
default:
|
||||
spi_cache_dummy = SPI0_R_FAST_DUMMY_CYCLELEN;
|
||||
break;
|
||||
}
|
||||
|
||||
/* dummy_len_plus values defined in ROM for SPI flash configuration */
|
||||
extern uint8_t g_rom_spiflash_dummy_len_plus[];
|
||||
switch (pfhdr->spi_speed) {
|
||||
case ESP_IMAGE_SPI_SPEED_80M:
|
||||
g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_80M;
|
||||
g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_80M;
|
||||
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_80M,
|
||||
SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
|
||||
drv = 3;
|
||||
break;
|
||||
case ESP_IMAGE_SPI_SPEED_40M:
|
||||
g_rom_spiflash_dummy_len_plus[0] = FLASH_IO_MATRIX_DUMMY_40M;
|
||||
g_rom_spiflash_dummy_len_plus[1] = FLASH_IO_MATRIX_DUMMY_40M;
|
||||
SET_PERI_REG_BITS(SPI_USER1_REG(0), SPI_USR_DUMMY_CYCLELEN_V, spi_cache_dummy + FLASH_IO_MATRIX_DUMMY_40M,
|
||||
SPI_USR_DUMMY_CYCLELEN_S); //DUMMY
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
uint32_t chip_ver = REG_GET_FIELD(EFUSE_BLK0_RDATA3_REG, EFUSE_RD_CHIP_VER_PKG);
|
||||
uint32_t pkg_ver = chip_ver & 0x7;
|
||||
|
||||
if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32D2WDQ5) {
|
||||
// For ESP32D2WD the SPI pins are already configured
|
||||
// flash clock signal should come from IO MUX.
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD2) {
|
||||
// For ESP32PICOD2 the SPI pins are already configured
|
||||
// flash clock signal should come from IO MUX.
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
} else if (pkg_ver == EFUSE_RD_CHIP_VER_PKG_ESP32PICOD4) {
|
||||
// For ESP32PICOD4 the SPI pins are already configured
|
||||
// flash clock signal should come from IO MUX.
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
} else {
|
||||
const uint32_t spiconfig = ets_efuse_get_spiconfig();
|
||||
if (spiconfig == EFUSE_SPICONFIG_SPI_DEFAULTS) {
|
||||
gpio_matrix_out(FLASH_CS_IO, SPICS0_OUT_IDX, 0, 0);
|
||||
gpio_matrix_out(FLASH_SPIQ_IO, SPIQ_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(FLASH_SPIQ_IO, SPIQ_IN_IDX, 0);
|
||||
gpio_matrix_out(FLASH_SPID_IO, SPID_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(FLASH_SPID_IO, SPID_IN_IDX, 0);
|
||||
gpio_matrix_out(FLASH_SPIWP_IO, SPIWP_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(FLASH_SPIWP_IO, SPIWP_IN_IDX, 0);
|
||||
gpio_matrix_out(FLASH_SPIHD_IO, SPIHD_OUT_IDX, 0, 0);
|
||||
gpio_matrix_in(FLASH_SPIHD_IO, SPIHD_IN_IDX, 0);
|
||||
//select pin function gpio
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA2_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, PIN_FUNC_GPIO);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, PIN_FUNC_GPIO);
|
||||
// flash clock signal should come from IO MUX.
|
||||
// set drive ability for clock
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, FUNC_SD_CLK_SPICLK);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, drv, FUN_DRV_S);
|
||||
|
||||
#if CONFIG_SPIRAM_TYPE_ESPPSRAM32
|
||||
uint32_t flash_id = g_rom_flashchip.device_id;
|
||||
if (flash_id == FLASH_ID_GD25LQ32C) {
|
||||
// Set drive ability for 1.8v flash in 80Mhz.
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA0_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA1_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA2_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_DATA3_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CMD_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
SET_PERI_REG_BITS(PERIPHS_IO_MUX_SD_CLK_U, FUN_DRV, 3, FUN_DRV_S);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void uart_console_configure(void)
|
||||
|
||||
@@ -114,18 +114,17 @@ void bootloader_random_enable(void)
|
||||
|
||||
void bootloader_random_disable(void)
|
||||
{
|
||||
/* Disable i2s clock */
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
|
||||
|
||||
|
||||
/* Reset some i2s configuration (possibly redundant as we reset entire
|
||||
I2S peripheral further down). */
|
||||
CLEAR_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_START);
|
||||
SET_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_RESET);
|
||||
CLEAR_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_RESET);
|
||||
CLEAR_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_CAMERA_EN);
|
||||
CLEAR_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_LCD_EN);
|
||||
CLEAR_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_DATA_ENABLE_TEST_EN);
|
||||
CLEAR_PERI_REG_MASK(I2S_CONF2_REG(0), I2S_DATA_ENABLE);
|
||||
|
||||
/* Disable i2s clock */
|
||||
DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(I2S_CONF_REG(0), I2S_RX_START);
|
||||
|
||||
/* Restore SYSCON mode registers */
|
||||
CLEAR_PERI_REG_MASK(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DIG_FORCE);
|
||||
|
||||
@@ -51,15 +51,12 @@
|
||||
#include "bootloader_common.h"
|
||||
#include "bootloader_utility.h"
|
||||
#include "bootloader_sha.h"
|
||||
#include "esp_efuse.h"
|
||||
|
||||
static const char* TAG = "boot";
|
||||
|
||||
/* Reduce literal size for some generic string literals */
|
||||
#define MAP_ERR_MSG "Image contains multiple %s segments. Only the last one will be mapped."
|
||||
|
||||
static bool ota_has_initial_contents;
|
||||
|
||||
static void load_image(const esp_image_metadata_t* image_data);
|
||||
static void unpack_load_app(const esp_image_metadata_t *data);
|
||||
static void set_cache_and_start_app(uint32_t drom_addr,
|
||||
@@ -70,34 +67,6 @@ static void set_cache_and_start_app(uint32_t drom_addr,
|
||||
uint32_t irom_size,
|
||||
uint32_t entry_addr);
|
||||
|
||||
// Read ota_info partition and fill array from two otadata structures.
|
||||
static esp_err_t read_otadata(const esp_partition_pos_t *ota_info, esp_ota_select_entry_t *two_otadata)
|
||||
{
|
||||
const esp_ota_select_entry_t *ota_select_map;
|
||||
if (ota_info->offset == 0) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
// partition table has OTA data partition
|
||||
if (ota_info->size < 2 * SPI_SEC_SIZE) {
|
||||
ESP_LOGE(TAG, "ota_info partition size %d is too small (minimum %d bytes)", ota_info->size, sizeof(esp_ota_select_entry_t));
|
||||
return ESP_FAIL; // can't proceed
|
||||
}
|
||||
|
||||
ESP_LOGD(TAG, "OTA data offset 0x%x", ota_info->offset);
|
||||
ota_select_map = bootloader_mmap(ota_info->offset, ota_info->size);
|
||||
if (!ota_select_map) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", ota_info->offset, ota_info->size);
|
||||
return ESP_FAIL; // can't proceed
|
||||
}
|
||||
|
||||
memcpy(&two_otadata[0], ota_select_map, sizeof(esp_ota_select_entry_t));
|
||||
memcpy(&two_otadata[1], (uint8_t *)ota_select_map + SPI_SEC_SIZE, sizeof(esp_ota_select_entry_t));
|
||||
bootloader_munmap(ota_select_map);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
bool bootloader_utility_load_partition_table(bootloader_state_t* bs)
|
||||
{
|
||||
const esp_partition_info_t *partitions;
|
||||
@@ -167,12 +136,6 @@ bool bootloader_utility_load_partition_table(bootloader_state_t* bs)
|
||||
case PART_SUBTYPE_DATA_NVS_KEYS:
|
||||
partition_usage = "NVS keys";
|
||||
break;
|
||||
case PART_SUBTYPE_DATA_EFUSE_EM:
|
||||
partition_usage = "efuse";
|
||||
#ifdef CONFIG_EFUSE_SECURE_VERSION_EMULATE
|
||||
esp_efuse_init(partition->pos.offset, partition->pos.size);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
partition_usage = "Unknown data";
|
||||
break;
|
||||
@@ -229,157 +192,73 @@ static void log_invalid_app_partition(int index)
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t write_otadata(esp_ota_select_entry_t *otadata, uint32_t offset, bool write_encrypted)
|
||||
{
|
||||
esp_err_t err = bootloader_flash_erase_sector(offset / FLASH_SECTOR_SIZE);
|
||||
if (err == ESP_OK) {
|
||||
err = bootloader_flash_write(offset, otadata, sizeof(esp_ota_select_entry_t), write_encrypted);
|
||||
}
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Error in write_otadata operation. err = 0x%x", err);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static bool check_anti_rollback(const esp_partition_pos_t *partition)
|
||||
{
|
||||
#ifdef CONFIG_APP_ANTI_ROLLBACK
|
||||
esp_app_desc_t app_desc;
|
||||
esp_err_t err = bootloader_common_get_partition_description(partition, &app_desc);
|
||||
return err == ESP_OK && esp_efuse_check_secure_version(app_desc.secure_version) == true;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_APP_ANTI_ROLLBACK
|
||||
static void update_anti_rollback(const esp_partition_pos_t *partition)
|
||||
{
|
||||
esp_app_desc_t app_desc;
|
||||
esp_err_t err = bootloader_common_get_partition_description(partition, &app_desc);
|
||||
if (err == ESP_OK) {
|
||||
esp_efuse_update_secure_version(app_desc.secure_version);
|
||||
}
|
||||
}
|
||||
|
||||
static int get_active_otadata_with_check_anti_rollback(const bootloader_state_t *bs, esp_ota_select_entry_t *two_otadata)
|
||||
{
|
||||
uint32_t ota_seq;
|
||||
uint32_t ota_slot;
|
||||
bool valid_otadata[2];
|
||||
|
||||
valid_otadata[0] = bootloader_common_ota_select_valid(&two_otadata[0]);
|
||||
valid_otadata[1] = bootloader_common_ota_select_valid(&two_otadata[1]);
|
||||
|
||||
bool sec_ver_valid_otadata[2] = { 0 };
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (valid_otadata[i] == true) {
|
||||
ota_seq = two_otadata[i].ota_seq - 1; // Raw OTA sequence number. May be more than # of OTA slots
|
||||
ota_slot = ota_seq % bs->app_count; // Actual OTA partition selection
|
||||
if (check_anti_rollback(&bs->ota[ota_slot]) == false) {
|
||||
// invalid. This otadata[i] will not be selected as active.
|
||||
ESP_LOGD(TAG, "OTA slot %d has an app with secure_version, this version is smaller than in the device. This OTA slot will not be selected.", ota_slot);
|
||||
} else {
|
||||
sec_ver_valid_otadata[i] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bootloader_common_select_otadata(two_otadata, sec_ver_valid_otadata, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
int bootloader_utility_get_selected_boot_partition(const bootloader_state_t *bs)
|
||||
{
|
||||
esp_ota_select_entry_t otadata[2];
|
||||
int boot_index = FACTORY_INDEX;
|
||||
esp_ota_select_entry_t sa,sb;
|
||||
const esp_ota_select_entry_t *ota_select_map;
|
||||
|
||||
if (bs->ota_info.offset == 0) {
|
||||
return FACTORY_INDEX;
|
||||
}
|
||||
|
||||
if (read_otadata(&bs->ota_info, otadata) != ESP_OK) {
|
||||
return INVALID_INDEX;
|
||||
}
|
||||
ota_has_initial_contents = false;
|
||||
|
||||
ESP_LOGD(TAG, "otadata[0]: sequence values 0x%08x", otadata[0].ota_seq);
|
||||
ESP_LOGD(TAG, "otadata[1]: sequence values 0x%08x", otadata[1].ota_seq);
|
||||
|
||||
#ifdef CONFIG_APP_ROLLBACK_ENABLE
|
||||
bool write_encrypted = esp_flash_encryption_enabled();
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
if (otadata[i].ota_state == ESP_OTA_IMG_PENDING_VERIFY) {
|
||||
ESP_LOGD(TAG, "otadata[%d] is marking as ABORTED", i);
|
||||
otadata[i].ota_state = ESP_OTA_IMG_ABORTED;
|
||||
write_otadata(&otadata[i], bs->ota_info.offset + FLASH_SECTOR_SIZE * i, write_encrypted);
|
||||
if (bs->ota_info.offset != 0) {
|
||||
// partition table has OTA data partition
|
||||
if (bs->ota_info.size < 2 * SPI_SEC_SIZE) {
|
||||
ESP_LOGE(TAG, "ota_info partition size %d is too small (minimum %d bytes)", bs->ota_info.size, sizeof(esp_ota_select_entry_t));
|
||||
return INVALID_INDEX; // can't proceed
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_APP_ANTI_ROLLBACK
|
||||
if ((bootloader_common_ota_select_invalid(&otadata[0]) &&
|
||||
bootloader_common_ota_select_invalid(&otadata[1])) ||
|
||||
bs->app_count == 0) {
|
||||
ESP_LOGD(TAG, "OTA sequence numbers both empty (all-0xFF) or partition table does not have bootable ota_apps (app_count=%d)", bs->app_count);
|
||||
if (bs->factory.offset != 0) {
|
||||
ESP_LOGI(TAG, "Defaulting to factory image");
|
||||
boot_index = FACTORY_INDEX;
|
||||
} else {
|
||||
ESP_LOGI(TAG, "No factory image, trying OTA 0");
|
||||
boot_index = 0;
|
||||
// Try to boot from ota_0.
|
||||
if ((otadata[0].ota_seq == UINT32_MAX || otadata[0].crc != bootloader_common_ota_select_crc(&otadata[0])) &&
|
||||
(otadata[1].ota_seq == UINT32_MAX || otadata[1].crc != bootloader_common_ota_select_crc(&otadata[1]))) {
|
||||
// Factory is not found and both otadata are initial(0xFFFFFFFF) or incorrect crc.
|
||||
// will set correct ota_seq.
|
||||
ota_has_initial_contents = true;
|
||||
ESP_LOGD(TAG, "OTA data offset 0x%x", bs->ota_info.offset);
|
||||
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 INVALID_INDEX; // can't proceed
|
||||
}
|
||||
memcpy(&sa, ota_select_map, sizeof(esp_ota_select_entry_t));
|
||||
memcpy(&sb, (uint8_t *)ota_select_map + SPI_SEC_SIZE, sizeof(esp_ota_select_entry_t));
|
||||
bootloader_munmap(ota_select_map);
|
||||
|
||||
ESP_LOGD(TAG, "OTA sequence values A 0x%08x B 0x%08x", sa.ota_seq, sb.ota_seq);
|
||||
if ((sa.ota_seq == UINT32_MAX && sb.ota_seq == UINT32_MAX) || (bs->app_count == 0)) {
|
||||
ESP_LOGD(TAG, "OTA sequence numbers both empty (all-0xFF) or partition table does not have bootable ota_apps (app_count=%d)", bs->app_count);
|
||||
if (bs->factory.offset != 0) {
|
||||
ESP_LOGI(TAG, "Defaulting to factory image");
|
||||
return FACTORY_INDEX;
|
||||
} else {
|
||||
ESP_LOGI(TAG, "No factory image, trying OTA 0");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
bool ota_valid = false;
|
||||
const char *ota_msg;
|
||||
int ota_seq; // Raw OTA sequence number. May be more than # of OTA slots
|
||||
if(bootloader_common_ota_select_valid(&sa) && bootloader_common_ota_select_valid(&sb)) {
|
||||
ota_valid = true;
|
||||
ota_msg = "Both OTA values";
|
||||
ota_seq = MAX(sa.ota_seq, sb.ota_seq) - 1;
|
||||
} else if(bootloader_common_ota_select_valid(&sa)) {
|
||||
ota_valid = true;
|
||||
ota_msg = "Only OTA sequence A is";
|
||||
ota_seq = sa.ota_seq - 1;
|
||||
} else if(bootloader_common_ota_select_valid(&sb)) {
|
||||
ota_valid = true;
|
||||
ota_msg = "Only OTA sequence B is";
|
||||
ota_seq = sb.ota_seq - 1;
|
||||
}
|
||||
|
||||
if (ota_valid) {
|
||||
int ota_slot = ota_seq % bs->app_count; // Actual OTA partition selection
|
||||
ESP_LOGD(TAG, "%s valid. Mapping seq %d -> OTA slot %d", ota_msg, ota_seq, ota_slot);
|
||||
return ota_slot;
|
||||
} else if (bs->factory.offset != 0) {
|
||||
ESP_LOGE(TAG, "ota data partition invalid, falling back to factory");
|
||||
return FACTORY_INDEX;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "ota data partition invalid and no factory, will try all partitions");
|
||||
return FACTORY_INDEX;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int active_otadata = bootloader_common_get_active_otadata(otadata);
|
||||
#else
|
||||
ESP_LOGI(TAG, "Enabled a check secure version of app for anti rollback");
|
||||
ESP_LOGI(TAG, "Secure version (from eFuse) = %d", esp_efuse_read_secure_version());
|
||||
// When CONFIG_APP_ANTI_ROLLBACK is enabled factory partition should not be in partition table, only two ota_app are there.
|
||||
if ((otadata[0].ota_seq == UINT32_MAX || otadata[0].crc != bootloader_common_ota_select_crc(&otadata[0])) &&
|
||||
(otadata[1].ota_seq == UINT32_MAX || otadata[1].crc != bootloader_common_ota_select_crc(&otadata[1]))) {
|
||||
ESP_LOGI(TAG, "otadata[0..1] in initial state");
|
||||
// both otadata are initial(0xFFFFFFFF) or incorrect crc.
|
||||
// will set correct ota_seq.
|
||||
ota_has_initial_contents = true;
|
||||
} else {
|
||||
int active_otadata = get_active_otadata_with_check_anti_rollback(bs, otadata);
|
||||
#endif
|
||||
if (active_otadata != -1) {
|
||||
ESP_LOGD(TAG, "Active otadata[%d]", active_otadata);
|
||||
uint32_t ota_seq = otadata[active_otadata].ota_seq - 1; // Raw OTA sequence number. May be more than # of OTA slots
|
||||
boot_index = ota_seq % bs->app_count; // Actual OTA partition selection
|
||||
ESP_LOGD(TAG, "Mapping seq %d -> OTA slot %d", ota_seq, boot_index);
|
||||
#ifdef CONFIG_APP_ROLLBACK_ENABLE
|
||||
if (otadata[active_otadata].ota_state == ESP_OTA_IMG_NEW) {
|
||||
ESP_LOGD(TAG, "otadata[%d] is selected as new and marked PENDING_VERIFY state", active_otadata);
|
||||
otadata[active_otadata].ota_state = ESP_OTA_IMG_PENDING_VERIFY;
|
||||
write_otadata(&otadata[active_otadata], bs->ota_info.offset + FLASH_SECTOR_SIZE * active_otadata, write_encrypted);
|
||||
}
|
||||
#endif // CONFIG_APP_ROLLBACK_ENABLE
|
||||
|
||||
#ifdef CONFIG_APP_ANTI_ROLLBACK
|
||||
if(otadata[active_otadata].ota_state == ESP_OTA_IMG_VALID) {
|
||||
update_anti_rollback(&bs->ota[boot_index]);
|
||||
}
|
||||
#endif // CONFIG_APP_ANTI_ROLLBACK
|
||||
|
||||
} else if (bs->factory.offset != 0) {
|
||||
ESP_LOGE(TAG, "ota data partition invalid, falling back to factory");
|
||||
boot_index = FACTORY_INDEX;
|
||||
} else {
|
||||
ESP_LOGE(TAG, "ota data partition invalid and no factory, will try all partitions");
|
||||
boot_index = FACTORY_INDEX;
|
||||
}
|
||||
}
|
||||
|
||||
return boot_index;
|
||||
// otherwise, start from factory app partition and let the search logic
|
||||
// proceed from there
|
||||
return FACTORY_INDEX;
|
||||
}
|
||||
|
||||
/* Return true if a partition has a valid app image that was successfully loaded */
|
||||
@@ -400,26 +279,6 @@ static bool try_load_partition(const esp_partition_pos_t *partition, esp_image_m
|
||||
return false;
|
||||
}
|
||||
|
||||
// ota_has_initial_contents flag is set if factory does not present in partition table and
|
||||
// otadata has initial content(0xFFFFFFFF), then set actual ota_seq.
|
||||
static void set_actual_ota_seq(const bootloader_state_t *bs, int index)
|
||||
{
|
||||
if (index > FACTORY_INDEX && ota_has_initial_contents == true) {
|
||||
esp_ota_select_entry_t otadata;
|
||||
memset(&otadata, 0xFF, sizeof(otadata));
|
||||
otadata.ota_seq = index + 1;
|
||||
otadata.ota_state = ESP_OTA_IMG_VALID;
|
||||
otadata.crc = bootloader_common_ota_select_crc(&otadata);
|
||||
|
||||
bool write_encrypted = esp_flash_encryption_enabled();
|
||||
write_otadata(&otadata, bs->ota_info.offset + FLASH_SECTOR_SIZE * 0, write_encrypted);
|
||||
ESP_LOGI(TAG, "Set actual ota_seq=%d in otadata[0]", otadata.ota_seq);
|
||||
#ifdef CONFIG_APP_ANTI_ROLLBACK
|
||||
update_anti_rollback(&bs->ota[index]);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#define TRY_LOG_FORMAT "Trying partition index %d offs 0x%x size 0x%x"
|
||||
|
||||
void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_index)
|
||||
@@ -444,8 +303,7 @@ void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_
|
||||
continue;
|
||||
}
|
||||
ESP_LOGD(TAG, TRY_LOG_FORMAT, index, part.offset, part.size);
|
||||
if (check_anti_rollback(&part) && try_load_partition(&part, &image_data)) {
|
||||
set_actual_ota_seq(bs, index);
|
||||
if (try_load_partition(&part, &image_data)) {
|
||||
load_image(&image_data);
|
||||
}
|
||||
log_invalid_app_partition(index);
|
||||
@@ -458,8 +316,7 @@ void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_
|
||||
continue;
|
||||
}
|
||||
ESP_LOGD(TAG, TRY_LOG_FORMAT, index, part.offset, part.size);
|
||||
if (check_anti_rollback(&part) && try_load_partition(&part, &image_data)) {
|
||||
set_actual_ota_seq(bs, index);
|
||||
if (try_load_partition(&part, &image_data)) {
|
||||
load_image(&image_data);
|
||||
}
|
||||
log_invalid_app_partition(index);
|
||||
@@ -478,71 +335,24 @@ void bootloader_utility_load_boot_image(const bootloader_state_t *bs, int start_
|
||||
// Copy loaded segments to RAM, set up caches for mapped segments, and start application.
|
||||
static void load_image(const esp_image_metadata_t* image_data)
|
||||
{
|
||||
/**
|
||||
* Rough steps for a first boot, when encryption and secure boot are both disabled:
|
||||
* 1) Generate secure boot key and write to EFUSE.
|
||||
* 2) Write plaintext digest based on plaintext bootloader
|
||||
* 3) Generate flash encryption key and write to EFUSE.
|
||||
* 4) Encrypt flash in-place including bootloader, then digest,
|
||||
* then app partitions and other encrypted partitions
|
||||
* 5) Burn EFUSE to enable flash encryption (FLASH_CRYPT_CNT)
|
||||
* 6) Burn EFUSE to enable secure boot (ABS_DONE_0)
|
||||
*
|
||||
* If power failure happens during Step 1, probably the next boot will continue from Step 2.
|
||||
* There is some small chance that EFUSEs will be part-way through being written so will be
|
||||
* somehow corrupted here. Thankfully this window of time is very small, but if that's the
|
||||
* case, one has to use the espefuse tool to manually set the remaining bits and enable R/W
|
||||
* protection. Once the relevant EFUSE bits are set and R/W protected, Step 1 will be skipped
|
||||
* successfully on further reboots.
|
||||
*
|
||||
* If power failure happens during Step 2, Step 1 will be skipped and Step 2 repeated:
|
||||
* the digest will get re-written on the next boot.
|
||||
*
|
||||
* If power failure happens during Step 3, it's possible that EFUSE was partially written
|
||||
* with the generated flash encryption key, though the time window for that would again
|
||||
* be very small. On reboot, Step 1 will be skipped and Step 2 repeated, though, Step 3
|
||||
* may fail due to the above mentioned reason, in which case, one has to use the espefuse
|
||||
* tool to manually set the remaining bits and enable R/W protection. Once the relevant EFUSE
|
||||
* bits are set and R/W protected, Step 3 will be skipped successfully on further reboots.
|
||||
*
|
||||
* If power failure happens after start of 4 and before end of 5, the next boot will fail
|
||||
* (bootloader header is encrypted and flash encryption isn't enabled yet, so it looks like
|
||||
* noise to the ROM bootloader). The check in the ROM is pretty basic so if the first byte of
|
||||
* ciphertext happens to be the magic byte E9 then it may try to boot, but it will definitely
|
||||
* crash (no chance that the remaining ciphertext will look like a valid bootloader image).
|
||||
* Only solution is to reflash with all plaintext and the whole process starts again: skips
|
||||
* Step 1, repeats Step 2, skips Step 3, etc.
|
||||
*
|
||||
* If power failure happens after 5 but before 6, the device will reboot with flash
|
||||
* encryption on and will regenerate an encrypted digest in Step 2. This should still
|
||||
* be valid as the input data for the digest is read via flash cache (so will be decrypted)
|
||||
* and the code in secure_boot_generate() tells bootloader_flash_write() to encrypt the data
|
||||
* on write if flash encryption is enabled. Steps 3 - 5 are skipped (encryption already on),
|
||||
* then Step 6 enables secure boot.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_SECURE_BOOT_ENABLED) || defined(CONFIG_FLASH_ENCRYPTION_ENABLED)
|
||||
esp_err_t err;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
/* Steps 1 & 2 (see above for full description):
|
||||
* 1) Generate secure boot EFUSE key
|
||||
* 2) Compute digest of plaintext bootloader
|
||||
*/
|
||||
err = esp_secure_boot_generate_digest();
|
||||
/* Generate secure digest from this bootloader to protect future
|
||||
modifications */
|
||||
ESP_LOGI(TAG, "Checking secure boot...");
|
||||
err = esp_secure_boot_permanently_enable();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Bootloader digest generation for secure boot failed (%d).", err);
|
||||
return;
|
||||
ESP_LOGE(TAG, "Bootloader digest generation failed (%d). SECURE BOOT IS NOT ENABLED.", err);
|
||||
/* Allow booting to continue, as the failure is probably
|
||||
due to user-configured EFUSEs for testing...
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FLASH_ENCRYPTION_ENABLED
|
||||
/* Steps 3, 4 & 5 (see above for full description):
|
||||
* 3) Generate flash encryption EFUSE key
|
||||
* 4) Encrypt flash contents
|
||||
* 5) Burn EFUSE to enable flash encryption
|
||||
*/
|
||||
/* encrypt flash */
|
||||
ESP_LOGI(TAG, "Checking flash encryption...");
|
||||
bool flash_encryption_enabled = esp_flash_encryption_enabled();
|
||||
err = esp_flash_encrypt_check_and_update();
|
||||
@@ -550,24 +360,7 @@ static void load_image(const esp_image_metadata_t* image_data)
|
||||
ESP_LOGE(TAG, "Flash encryption check failed (%d).", err);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
/* Step 6 (see above for full description):
|
||||
* 6) Burn EFUSE to enable secure boot
|
||||
*/
|
||||
ESP_LOGI(TAG, "Checking secure boot...");
|
||||
err = esp_secure_boot_permanently_enable();
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "FAILED TO ENABLE SECURE BOOT (%d).", err);
|
||||
/* Panic here as secure boot is not properly enabled
|
||||
due to one of the reasons in above function
|
||||
*/
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FLASH_ENCRYPTION_ENABLED
|
||||
if (!flash_encryption_enabled && esp_flash_encryption_enabled()) {
|
||||
/* Flash encryption was just enabled for the first time,
|
||||
so issue a system reset to ensure flash encryption
|
||||
|
||||
114
components/bootloader_support/src/efuse.c
Normal file
114
components/bootloader_support/src/efuse.c
Normal file
@@ -0,0 +1,114 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_log.h"
|
||||
#include <string.h>
|
||||
#include "bootloader_random.h"
|
||||
|
||||
#define EFUSE_CONF_WRITE 0x5A5A /* efuse_pgm_op_ena, force no rd/wr disable */
|
||||
#define EFUSE_CONF_READ 0x5AA5 /* efuse_read_op_ena, release force */
|
||||
|
||||
#define EFUSE_CMD_PGM 0x02
|
||||
#define EFUSE_CMD_READ 0x01
|
||||
|
||||
static const char *TAG = "efuse";
|
||||
|
||||
void esp_efuse_burn_new_values(void)
|
||||
{
|
||||
REG_WRITE(EFUSE_CONF_REG, EFUSE_CONF_WRITE);
|
||||
REG_WRITE(EFUSE_CMD_REG, EFUSE_CMD_PGM);
|
||||
while (REG_READ(EFUSE_CMD_REG) != 0) {
|
||||
}
|
||||
REG_WRITE(EFUSE_CONF_REG, EFUSE_CONF_READ);
|
||||
REG_WRITE(EFUSE_CMD_REG, EFUSE_CMD_READ);
|
||||
while (REG_READ(EFUSE_CMD_REG) != 0) {
|
||||
}
|
||||
esp_efuse_reset();
|
||||
}
|
||||
|
||||
void esp_efuse_reset(void)
|
||||
{
|
||||
REG_WRITE(EFUSE_CONF_REG, EFUSE_CONF_READ);
|
||||
const uint32_t block_start[4] = { EFUSE_BLK0_WDATA0_REG, EFUSE_BLK1_WDATA0_REG,
|
||||
EFUSE_BLK2_WDATA0_REG, EFUSE_BLK3_WDATA0_REG };
|
||||
const uint32_t block_end[4] = { EFUSE_BLK0_WDATA6_REG, EFUSE_BLK1_WDATA7_REG,
|
||||
EFUSE_BLK2_WDATA7_REG, EFUSE_BLK3_WDATA7_REG };
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (uint32_t r = block_start[i]; r <= block_end[i]; r+= 4) {
|
||||
REG_WRITE(r, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void esp_efuse_disable_basic_rom_console(void)
|
||||
{
|
||||
if ((REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_RD_CONSOLE_DEBUG_DISABLE) == 0) {
|
||||
ESP_EARLY_LOGI(TAG, "Disable BASIC ROM Console fallback via efuse...");
|
||||
esp_efuse_reset();
|
||||
REG_WRITE(EFUSE_BLK0_WDATA6_REG, EFUSE_RD_CONSOLE_DEBUG_DISABLE);
|
||||
esp_efuse_burn_new_values();
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t esp_efuse_apply_34_encoding(const uint8_t *in_bytes, uint32_t *out_words, size_t in_bytes_len)
|
||||
{
|
||||
if (in_bytes == NULL || out_words == NULL || in_bytes_len % 6 != 0) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
while (in_bytes_len > 0) {
|
||||
uint8_t out[8];
|
||||
uint8_t xor = 0;
|
||||
uint8_t mul = 0;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
xor ^= in_bytes[i];
|
||||
mul += (i + 1) * __builtin_popcount(in_bytes[i]);
|
||||
}
|
||||
|
||||
memcpy(out, in_bytes, 6); // Data bytes
|
||||
out[6] = xor;
|
||||
out[7] = mul;
|
||||
|
||||
memcpy(out_words, out, 8);
|
||||
|
||||
in_bytes_len -= 6;
|
||||
in_bytes += 6;
|
||||
out_words += 2;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void esp_efuse_write_random_key(uint32_t blk_wdata0_reg)
|
||||
{
|
||||
uint32_t buf[8];
|
||||
uint8_t raw[24];
|
||||
uint32_t coding_scheme = REG_READ(EFUSE_BLK0_RDATA6_REG) & EFUSE_CODING_SCHEME_M;
|
||||
|
||||
if (coding_scheme == EFUSE_CODING_SCHEME_VAL_NONE) {
|
||||
bootloader_fill_random(buf, sizeof(buf));
|
||||
} else { // 3/4 Coding Scheme
|
||||
bootloader_fill_random(raw, sizeof(raw));
|
||||
esp_err_t r = esp_efuse_apply_34_encoding(raw, buf, sizeof(raw));
|
||||
assert(r == ESP_OK);
|
||||
}
|
||||
|
||||
ESP_LOGV(TAG, "Writing random values to address 0x%08x", blk_wdata0_reg);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
ESP_LOGV(TAG, "EFUSE_BLKx_WDATA%d_REG = 0x%08x", i, buf[i]);
|
||||
REG_WRITE(blk_wdata0_reg + 4*i, buf[i]);
|
||||
}
|
||||
bzero(buf, sizeof(buf));
|
||||
bzero(raw, sizeof(raw));
|
||||
}
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <bootloader_random.h>
|
||||
#include <bootloader_sha.h>
|
||||
#include "bootloader_util.h"
|
||||
#include "bootloader_common.h"
|
||||
|
||||
/* Checking signatures as part of verifying images is necessary:
|
||||
- Always if secure boot is enabled
|
||||
@@ -281,9 +280,6 @@ static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t
|
||||
}
|
||||
err = ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
if (bootloader_common_check_chip_validity(image, ESP_IMAGE_APPLICATION) != ESP_OK) {
|
||||
err = ESP_ERR_IMAGE_INVALID;
|
||||
}
|
||||
if (!silent) {
|
||||
if (image->spi_mode > ESP_IMAGE_SPI_MODE_SLOW_READ) {
|
||||
ESP_LOGW(TAG, "image at 0x%x has invalid SPI mode %d", src_addr, image->spi_mode);
|
||||
@@ -372,22 +368,24 @@ static esp_err_t process_segment(int index, uint32_t flash_addr, esp_image_segme
|
||||
}
|
||||
#endif // BOOTLOADER_BUILD
|
||||
|
||||
uint32_t free_page_count = bootloader_mmap_get_free_pages();
|
||||
ESP_LOGD(TAG, "free data page_count 0x%08x", free_page_count);
|
||||
|
||||
int32_t data_len_remain = data_len;
|
||||
while (data_len_remain > 0) {
|
||||
uint32_t offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0) ? 1 : 0;
|
||||
/* Data we could map in case we are not aligned to PAGE boundary is one page size lesser. */
|
||||
data_len = MIN(data_len_remain, ((free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE));
|
||||
err = process_segment_data(load_addr, data_addr, data_len, do_load, sha_handle, checksum);
|
||||
#ifndef BOOTLOADER_BUILD
|
||||
uint32_t free_page_count = spi_flash_mmap_get_free_pages(SPI_FLASH_MMAP_DATA);
|
||||
ESP_LOGD(TAG, "free data page_count 0x%08x",free_page_count);
|
||||
uint32_t offset_page = 0;
|
||||
while (data_len >= free_page_count * SPI_FLASH_MMU_PAGE_SIZE) {
|
||||
offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0)?1:0;
|
||||
err = process_segment_data(load_addr, data_addr, (free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE, do_load, sha_handle, checksum);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
data_addr += data_len;
|
||||
data_len_remain -= data_len;
|
||||
data_addr += (free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE;
|
||||
data_len -= (free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE;
|
||||
}
|
||||
#endif
|
||||
err = process_segment_data(load_addr, data_addr, data_len, do_load, sha_handle, checksum);
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
|
||||
err:
|
||||
|
||||
@@ -205,14 +205,6 @@ static esp_err_t encrypt_flash_contents(uint32_t flash_crypt_cnt, bool flash_cry
|
||||
uint32_t new_flash_crypt_cnt = flash_crypt_cnt + (1 << (ffs_inv - 1));
|
||||
ESP_LOGD(TAG, "FLASH_CRYPT_CNT 0x%x -> 0x%x", flash_crypt_cnt, new_flash_crypt_cnt);
|
||||
REG_SET_FIELD(EFUSE_BLK0_WDATA0_REG, EFUSE_FLASH_CRYPT_CNT, new_flash_crypt_cnt);
|
||||
|
||||
#ifdef CONFIG_FLASH_ENCRYPTION_DISABLE_PLAINTEXT
|
||||
ESP_LOGI(TAG, "Write protecting FLASH_CRYPT_CNT efuse...");
|
||||
REG_SET_BIT(EFUSE_BLK0_WDATA0_REG, EFUSE_WR_DIS_FLASH_CRYPT_CNT);
|
||||
#else
|
||||
ESP_LOGW(TAG, "Not disabling FLASH_CRYPT_CNT - plaintext flashing is still possible");
|
||||
#endif
|
||||
|
||||
esp_efuse_burn_new_values();
|
||||
|
||||
ESP_LOGI(TAG, "Flash encryption completed");
|
||||
@@ -233,18 +225,18 @@ static esp_err_t encrypt_bootloader()
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||
/* If secure boot is enabled and bootloader was plaintext, also
|
||||
* need to encrypt secure boot IV+digest.
|
||||
*/
|
||||
ESP_LOGD(TAG, "Encrypting secure bootloader IV & digest...");
|
||||
err = esp_flash_encrypt_region(FLASH_OFFS_SECURE_BOOT_IV_DIGEST,
|
||||
FLASH_SECTOR_SIZE);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to encrypt bootloader IV & digest in place: 0x%x", err);
|
||||
return err;
|
||||
if (esp_secure_boot_enabled()) {
|
||||
/* If secure boot is enabled and bootloader was plaintext, also
|
||||
need to encrypt secure boot IV+digest.
|
||||
*/
|
||||
ESP_LOGD(TAG, "Encrypting secure bootloader IV & digest...");
|
||||
err = esp_flash_encrypt_region(FLASH_OFFS_SECURE_BOOT_IV_DIGEST,
|
||||
FLASH_SECTOR_SIZE);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to encrypt bootloader IV & digest in place: 0x%x", err);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
ESP_LOGW(TAG, "no valid bootloader was found");
|
||||
|
||||
@@ -36,12 +36,6 @@
|
||||
#include "esp_flash_encrypt.h"
|
||||
#include "esp_efuse.h"
|
||||
|
||||
/* The following API implementations are used only when called
|
||||
* from the bootloader code.
|
||||
*/
|
||||
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
|
||||
static const char* TAG = "secure_boot";
|
||||
|
||||
/**
|
||||
@@ -101,15 +95,18 @@ static bool secure_boot_generate(uint32_t image_len){
|
||||
/* Burn values written to the efuse write registers */
|
||||
static inline void burn_efuses()
|
||||
{
|
||||
#ifdef CONFIG_SECURE_BOOT_TEST_MODE
|
||||
ESP_LOGE(TAG, "SECURE BOOT TEST MODE. Not really burning any efuses! NOT SECURE");
|
||||
#else
|
||||
esp_efuse_burn_new_values();
|
||||
#endif
|
||||
}
|
||||
|
||||
esp_err_t esp_secure_boot_generate_digest(void)
|
||||
{
|
||||
esp_err_t esp_secure_boot_permanently_enable(void) {
|
||||
esp_err_t err;
|
||||
if (esp_secure_boot_enabled()) {
|
||||
ESP_LOGI(TAG, "bootloader secure boot is already enabled."
|
||||
" No need to generate digest. continuing..");
|
||||
if (esp_secure_boot_enabled())
|
||||
{
|
||||
ESP_LOGI(TAG, "bootloader secure boot is already enabled, continuing..");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -127,7 +124,6 @@ esp_err_t esp_secure_boot_generate_digest(void)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Generate secure boot key and keep in EFUSE */
|
||||
uint32_t dis_reg = REG_READ(EFUSE_BLK0_RDATA0_REG);
|
||||
bool efuse_key_read_protected = dis_reg & EFUSE_RD_DIS_BLK2;
|
||||
bool efuse_key_write_protected = dis_reg & EFUSE_WR_DIS_BLK2;
|
||||
@@ -144,11 +140,16 @@ esp_err_t esp_secure_boot_generate_digest(void)
|
||||
ESP_LOGI(TAG, "Generating new secure boot key...");
|
||||
esp_efuse_write_random_key(EFUSE_BLK2_WDATA0_REG);
|
||||
burn_efuses();
|
||||
ESP_LOGI(TAG, "Read & write protecting new key...");
|
||||
REG_WRITE(EFUSE_BLK0_WDATA0_REG, EFUSE_WR_DIS_BLK2 | EFUSE_RD_DIS_BLK2);
|
||||
burn_efuses();
|
||||
efuse_key_read_protected = true;
|
||||
efuse_key_write_protected = true;
|
||||
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Using pre-loaded secure boot key in EFUSE block 2");
|
||||
}
|
||||
|
||||
/* Generate secure boot digest using programmed key in EFUSE */
|
||||
ESP_LOGI(TAG, "Generating secure boot digest...");
|
||||
uint32_t image_len = bootloader_data.image_len;
|
||||
if(bootloader_data.image.hash_appended) {
|
||||
@@ -161,28 +162,7 @@ esp_err_t esp_secure_boot_generate_digest(void)
|
||||
}
|
||||
ESP_LOGI(TAG, "Digest generation complete.");
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_secure_boot_permanently_enable(void)
|
||||
{
|
||||
if (esp_secure_boot_enabled()) {
|
||||
ESP_LOGI(TAG, "bootloader secure boot is already enabled, continuing..");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
uint32_t dis_reg = REG_READ(EFUSE_BLK0_RDATA0_REG);
|
||||
bool efuse_key_read_protected = dis_reg & EFUSE_RD_DIS_BLK2;
|
||||
bool efuse_key_write_protected = dis_reg & EFUSE_WR_DIS_BLK2;
|
||||
if (efuse_key_read_protected == false
|
||||
&& efuse_key_write_protected == false) {
|
||||
ESP_LOGI(TAG, "Read & write protecting new key...");
|
||||
REG_WRITE(EFUSE_BLK0_WDATA0_REG, EFUSE_WR_DIS_BLK2 | EFUSE_RD_DIS_BLK2);
|
||||
burn_efuses();
|
||||
efuse_key_read_protected = true;
|
||||
efuse_key_write_protected = true;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SECURE_BOOT_TEST_MODE
|
||||
if (!efuse_key_read_protected) {
|
||||
ESP_LOGE(TAG, "Pre-loaded key is not read protected. Refusing to blow secure boot efuse.");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
@@ -191,6 +171,7 @@ esp_err_t esp_secure_boot_permanently_enable(void)
|
||||
ESP_LOGE(TAG, "Pre-loaded key is not write protected. Refusing to blow secure boot efuse.");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "blowing secure boot efuse...");
|
||||
ESP_LOGD(TAG, "before updating, EFUSE_BLK0_RDATA6 %x", REG_READ(EFUSE_BLK0_RDATA6_REG));
|
||||
@@ -219,9 +200,11 @@ esp_err_t esp_secure_boot_permanently_enable(void)
|
||||
ESP_LOGI(TAG, "secure boot is now enabled for bootloader image");
|
||||
return ESP_OK;
|
||||
} else {
|
||||
#ifdef CONFIG_SECURE_BOOT_TEST_MODE
|
||||
ESP_LOGE(TAG, "secure boot not enabled due to test mode");
|
||||
#else
|
||||
ESP_LOGE(TAG, "secure boot not enabled for bootloader image, EFUSE_RD_ABS_DONE_0 is probably write protected!");
|
||||
#endif
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #ifdef BOOTLOADER_BUILD
|
||||
|
||||
@@ -21,7 +21,12 @@
|
||||
|
||||
#include "uECC.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
#include "rom/sha.h"
|
||||
typedef SHA_CTX sha_context;
|
||||
#else
|
||||
#include "mbedtls/sha256.h"
|
||||
#endif
|
||||
|
||||
static const char* TAG = "secure_boot";
|
||||
|
||||
@@ -32,9 +37,6 @@ extern const uint8_t signature_verification_key_end[] asm("_binary_signature_ver
|
||||
|
||||
#define DIGEST_LEN 32
|
||||
|
||||
/* Mmap source address mask */
|
||||
#define MMAP_ALIGNED_MASK 0x0000FFFF
|
||||
|
||||
esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
|
||||
{
|
||||
uint8_t digest[DIGEST_LEN];
|
||||
@@ -43,44 +45,26 @@ esp_err_t esp_secure_boot_verify_signature(uint32_t src_addr, uint32_t length)
|
||||
|
||||
ESP_LOGD(TAG, "verifying signature src_addr 0x%x length 0x%x", src_addr, length);
|
||||
|
||||
bootloader_sha256_handle_t handle = bootloader_sha256_start();
|
||||
|
||||
uint32_t free_page_count = bootloader_mmap_get_free_pages();
|
||||
ESP_LOGD(TAG, "free data page_count 0x%08x", free_page_count);
|
||||
|
||||
int32_t data_len_remain = length;
|
||||
uint32_t data_addr = src_addr;
|
||||
while (data_len_remain > 0) {
|
||||
uint32_t offset_page = ((data_addr & MMAP_ALIGNED_MASK) != 0) ? 1 : 0;
|
||||
/* Data we could map in case we are not aligned to PAGE boundary is one page size lesser. */
|
||||
uint32_t data_len = MIN(data_len_remain, ((free_page_count - offset_page) * SPI_FLASH_MMU_PAGE_SIZE));
|
||||
data = (const uint8_t *) bootloader_mmap(data_addr, data_len);
|
||||
if(!data) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", data_addr, data_len);
|
||||
bootloader_sha256_finish(handle, NULL);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
bootloader_sha256_data(handle, data, data_len);
|
||||
bootloader_munmap(data);
|
||||
|
||||
data_addr += data_len;
|
||||
data_len_remain -= data_len;
|
||||
}
|
||||
|
||||
/* Done! Get the digest */
|
||||
bootloader_sha256_finish(handle, digest);
|
||||
|
||||
// Map the signature block
|
||||
sigblock = (const esp_secure_boot_sig_block_t *) bootloader_mmap(src_addr + length, sizeof(esp_secure_boot_sig_block_t));
|
||||
if(!sigblock) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr + length, sizeof(esp_secure_boot_sig_block_t));
|
||||
data = bootloader_mmap(src_addr, length + sizeof(esp_secure_boot_sig_block_t));
|
||||
if(data == NULL) {
|
||||
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", src_addr, length+sizeof(esp_secure_boot_sig_block_t));
|
||||
return ESP_FAIL;
|
||||
}
|
||||
// Verify the signature
|
||||
esp_err_t err = esp_secure_boot_verify_signature_block(sigblock, digest);
|
||||
// Unmap
|
||||
bootloader_munmap(sigblock);
|
||||
|
||||
// Calculate digest of main image
|
||||
#ifdef BOOTLOADER_BUILD
|
||||
bootloader_sha256_handle_t handle = bootloader_sha256_start();
|
||||
bootloader_sha256_data(handle, data, length);
|
||||
bootloader_sha256_finish(handle, digest);
|
||||
#else
|
||||
/* Use thread-safe mbedTLS version */
|
||||
mbedtls_sha256_ret(data, length, digest, 0);
|
||||
#endif
|
||||
|
||||
// Map the signature block and verify the signature
|
||||
sigblock = (const esp_secure_boot_sig_block_t *)(data + length);
|
||||
esp_err_t err = esp_secure_boot_verify_signature_block(sigblock, digest);
|
||||
bootloader_munmap(data);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
#include <stdint.h>
|
||||
#include <strings.h>
|
||||
#include "esp_efuse.h"
|
||||
#include "../src/esp_efuse_utility.h"
|
||||
#include "soc/efuse_reg.h"
|
||||
#include "unity.h"
|
||||
#include "bootloader_random.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t unencoded[24];
|
||||
@@ -74,7 +71,7 @@ static const coding_scheme_test_t coding_scheme_data[] = {
|
||||
},
|
||||
};
|
||||
|
||||
TEST_CASE("Test 3/4 Coding Scheme Algorithm", "[efuse]")
|
||||
TEST_CASE("Test 3/4 Coding Scheme Algorithm", "[bootloader_support]")
|
||||
{
|
||||
const int num_tests = sizeof(coding_scheme_data)/sizeof(coding_scheme_test_t);
|
||||
for (int i = 0; i < num_tests; i++) {
|
||||
@@ -95,110 +92,3 @@ TEST_CASE("Test 3/4 Coding Scheme Algorithm", "[efuse]")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Test Coding Scheme for efuse manager", "[efuse]")
|
||||
{
|
||||
int count_useful_reg = 0;
|
||||
int useful_data_in_byte;
|
||||
uint8_t buf[32];
|
||||
uint32_t encoded[8];
|
||||
bootloader_random_enable();
|
||||
esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK2);
|
||||
if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
|
||||
printf("EFUSE_CODING_SCHEME_NONE\n");
|
||||
count_useful_reg = 8;
|
||||
} else if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
|
||||
printf("EFUSE_CODING_SCHEME_3_4\n");
|
||||
count_useful_reg = 6;
|
||||
} else if (coding_scheme == EFUSE_CODING_SCHEME_REPEAT) {
|
||||
printf("EFUSE_CODING_SCHEME_REPEAT\n");
|
||||
count_useful_reg = 4;
|
||||
}
|
||||
useful_data_in_byte = count_useful_reg * 4;
|
||||
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
printf("Test case %d...\n", i);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
memset(encoded, 0, sizeof(encoded));
|
||||
// get test data
|
||||
bootloader_fill_random(buf, useful_data_in_byte);
|
||||
memset(buf, 0, i);
|
||||
|
||||
esp_efuse_utility_reset();
|
||||
|
||||
for (int j = 0; j < count_useful_reg; ++j) {
|
||||
REG_WRITE(EFUSE_BLK2_WDATA0_REG + j * 4, *((uint32_t*)buf + j));
|
||||
}
|
||||
|
||||
TEST_ESP_OK(esp_efuse_utility_apply_new_coding_scheme());
|
||||
|
||||
uint32_t w_data_after_coding[8] = { 0 };
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
w_data_after_coding[j] = REG_READ(EFUSE_BLK2_WDATA0_REG + j * 4);
|
||||
}
|
||||
|
||||
if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
|
||||
memcpy((uint8_t*)encoded, buf, sizeof(buf));
|
||||
} else if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
|
||||
TEST_ESP_OK(esp_efuse_apply_34_encoding(buf, encoded, useful_data_in_byte));
|
||||
} else if (coding_scheme == EFUSE_CODING_SCHEME_REPEAT) {
|
||||
for (int j = 0; j < count_useful_reg; ++j) {
|
||||
encoded[j] = *((uint32_t*)buf + j);
|
||||
encoded[j + 4] = encoded[j];
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_EFUSE_VIRTUAL
|
||||
printf("Data from W reg\n");
|
||||
esp_efuse_utility_erase_virt_blocks();
|
||||
esp_efuse_utility_burn_efuses();
|
||||
esp_efuse_utility_debug_dump_blocks();
|
||||
printf("Data from encoded\n");
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
printf("0x%08x ", encoded[j]);
|
||||
}
|
||||
printf("\nData from w_data_after_coding\n");
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
printf("0x%08x ", w_data_after_coding[j]);
|
||||
}
|
||||
|
||||
printf("\nData from buf\n");
|
||||
for (int j = 0; j < 8; ++j) {
|
||||
printf("0x%08x ", *((uint32_t*)buf + j));
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
TEST_ASSERT_EQUAL_HEX32_ARRAY(encoded, w_data_after_coding, 8);
|
||||
}
|
||||
esp_efuse_utility_reset();
|
||||
bootloader_random_disable();
|
||||
}
|
||||
|
||||
TEST_CASE("Test data does not match the coding scheme", "[efuse]")
|
||||
{
|
||||
int count_useful_reg = 0;
|
||||
esp_efuse_coding_scheme_t coding_scheme = esp_efuse_get_coding_scheme(EFUSE_BLK2);
|
||||
if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
|
||||
printf("EFUSE_CODING_SCHEME_NONE\n");
|
||||
count_useful_reg = 8;
|
||||
} else if (coding_scheme == EFUSE_CODING_SCHEME_3_4) {
|
||||
printf("EFUSE_CODING_SCHEME_3_4\n");
|
||||
count_useful_reg = 6 + 1;
|
||||
} else if (coding_scheme == EFUSE_CODING_SCHEME_REPEAT) {
|
||||
printf("EFUSE_CODING_SCHEME_REPEAT\n");
|
||||
count_useful_reg = 4 + 1;
|
||||
}
|
||||
|
||||
esp_efuse_utility_reset();
|
||||
|
||||
for (int i = 0; i < count_useful_reg; ++i) {
|
||||
REG_WRITE(EFUSE_BLK2_WDATA0_REG + i * 4, 0xABCDEF01 + i);
|
||||
}
|
||||
|
||||
if (coding_scheme == EFUSE_CODING_SCHEME_NONE) {
|
||||
TEST_ESP_OK(esp_efuse_utility_apply_new_coding_scheme());
|
||||
} else {
|
||||
TEST_ESP_ERR(ESP_ERR_CODING, esp_efuse_utility_apply_new_coding_scheme());
|
||||
}
|
||||
|
||||
esp_efuse_utility_reset();
|
||||
}
|
||||
@@ -6,20 +6,18 @@ if(CONFIG_BT_ENABLED)
|
||||
if(CONFIG_BLUEDROID_ENABLED)
|
||||
|
||||
list(APPEND COMPONENT_PRIV_INCLUDEDIRS
|
||||
common/btc/include
|
||||
common/include
|
||||
bluedroid/bta/include
|
||||
bluedroid/bta/ar/include
|
||||
bluedroid/bta/av/include
|
||||
bluedroid/bta/dm/include
|
||||
bluedroid/bta/gatt/include
|
||||
bluedroid/bta/hf_client/include
|
||||
bluedroid/bta/hh/include
|
||||
bluedroid/bta/jv/include
|
||||
bluedroid/bta/sdp/include
|
||||
bluedroid/bta/sys/include
|
||||
bluedroid/device/include
|
||||
bluedroid/hci/include
|
||||
bluedroid/osi/include
|
||||
bluedroid/external/sbc/decoder/include
|
||||
bluedroid/external/sbc/encoder/include
|
||||
bluedroid/btc/profile/esp/blufi/include
|
||||
@@ -39,29 +37,11 @@ if(CONFIG_BT_ENABLED)
|
||||
bluedroid/stack/a2dp/include
|
||||
bluedroid/stack/rfcomm/include
|
||||
bluedroid/stack/include
|
||||
bluedroid/common/include
|
||||
common/btc/include
|
||||
common/include)
|
||||
bluedroid/common/include)
|
||||
|
||||
list(APPEND COMPONENT_ADD_INCLUDEDIRS bluedroid/api/include/api
|
||||
common/osi/include)
|
||||
list(APPEND COMPONENT_ADD_INCLUDEDIRS bluedroid/api/include/api)
|
||||
|
||||
list(APPEND COMPONENT_SRCS "common/btc/core/btc_alarm.c"
|
||||
"common/btc/core/btc_manage.c"
|
||||
"common/btc/core/btc_task.c"
|
||||
"common/osi/alarm.c"
|
||||
"common/osi/allocator.c"
|
||||
"common/osi/buffer.c"
|
||||
"common/osi/config.c"
|
||||
"common/osi/fixed_queue.c"
|
||||
"common/osi/future.c"
|
||||
"common/osi/hash_functions.c"
|
||||
"common/osi/hash_map.c"
|
||||
"common/osi/list.c"
|
||||
"common/osi/mutex.c"
|
||||
"common/osi/osi.c"
|
||||
"common/osi/semaphore.c"
|
||||
"bluedroid/api/esp_a2dp_api.c"
|
||||
list(APPEND COMPONENT_SRCS "bluedroid/api/esp_a2dp_api.c"
|
||||
"bluedroid/api/esp_avrc_api.c"
|
||||
"bluedroid/api/esp_blufi_api.c"
|
||||
"bluedroid/api/esp_bt_device.c"
|
||||
@@ -113,14 +93,6 @@ if(CONFIG_BT_ENABLED)
|
||||
"bluedroid/bta/jv/bta_jv_api.c"
|
||||
"bluedroid/bta/jv/bta_jv_cfg.c"
|
||||
"bluedroid/bta/jv/bta_jv_main.c"
|
||||
"bluedroid/bta/hf_client/bta_hf_client_act.c"
|
||||
"bluedroid/bta/hf_client/bta_hf_client_api.c"
|
||||
"bluedroid/bta/hf_client/bta_hf_client_at.c"
|
||||
"bluedroid/bta/hf_client/bta_hf_client_cmd.c"
|
||||
"bluedroid/bta/hf_client/bta_hf_client_main.c"
|
||||
"bluedroid/bta/hf_client/bta_hf_client_rfc.c"
|
||||
"bluedroid/bta/hf_client/bta_hf_client_sco.c"
|
||||
"bluedroid/bta/hf_client/bta_hf_client_sdp.c"
|
||||
"bluedroid/bta/sdp/bta_sdp.c"
|
||||
"bluedroid/bta/sdp/bta_sdp_act.c"
|
||||
"bluedroid/bta/sdp/bta_sdp_api.c"
|
||||
@@ -128,15 +100,18 @@ if(CONFIG_BT_ENABLED)
|
||||
"bluedroid/bta/sys/bta_sys_conn.c"
|
||||
"bluedroid/bta/sys/bta_sys_main.c"
|
||||
"bluedroid/bta/sys/utl.c"
|
||||
"bluedroid/btc/core/btc_alarm.c"
|
||||
"bluedroid/btc/core/btc_ble_storage.c"
|
||||
"bluedroid/btc/core/btc_config.c"
|
||||
"bluedroid/btc/core/btc_dev.c"
|
||||
"bluedroid/btc/core/btc_dm.c"
|
||||
"bluedroid/btc/core/btc_main.c"
|
||||
"bluedroid/btc/core/btc_manage.c"
|
||||
"bluedroid/btc/core/btc_profile_queue.c"
|
||||
"bluedroid/btc/core/btc_sec.c"
|
||||
"bluedroid/btc/core/btc_sm.c"
|
||||
"bluedroid/btc/core/btc_storage.c"
|
||||
"bluedroid/btc/core/btc_task.c"
|
||||
"bluedroid/btc/core/btc_util.c"
|
||||
"bluedroid/btc/profile/esp/blufi/blufi_prf.c"
|
||||
"bluedroid/btc/profile/esp/blufi/blufi_protocol.c"
|
||||
@@ -147,8 +122,6 @@ if(CONFIG_BT_ENABLED)
|
||||
"bluedroid/btc/profile/std/a2dp/btc_a2dp_source.c"
|
||||
"bluedroid/btc/profile/std/a2dp/btc_av.c"
|
||||
"bluedroid/btc/profile/std/avrc/btc_avrc.c"
|
||||
"bluedroid/btc/profile/std/hf_client/btc_hf_client.c"
|
||||
"bluedroid/btc/profile/std/hf_client/bta_hf_client_co.c"
|
||||
"bluedroid/btc/profile/std/gap/btc_gap_ble.c"
|
||||
"bluedroid/btc/profile/std/gap/btc_gap_bt.c"
|
||||
"bluedroid/btc/profile/std/gatt/btc_gatt_common.c"
|
||||
@@ -189,6 +162,18 @@ if(CONFIG_BT_ENABLED)
|
||||
"bluedroid/hci/packet_fragmenter.c"
|
||||
"bluedroid/main/bte_init.c"
|
||||
"bluedroid/main/bte_main.c"
|
||||
"bluedroid/osi/alarm.c"
|
||||
"bluedroid/osi/allocator.c"
|
||||
"bluedroid/osi/buffer.c"
|
||||
"bluedroid/osi/config.c"
|
||||
"bluedroid/osi/fixed_queue.c"
|
||||
"bluedroid/osi/future.c"
|
||||
"bluedroid/osi/hash_functions.c"
|
||||
"bluedroid/osi/hash_map.c"
|
||||
"bluedroid/osi/list.c"
|
||||
"bluedroid/osi/mutex.c"
|
||||
"bluedroid/osi/osi.c"
|
||||
"bluedroid/osi/semaphore.c"
|
||||
"bluedroid/stack/a2dp/a2d_api.c"
|
||||
"bluedroid/stack/a2dp/a2d_sbc.c"
|
||||
"bluedroid/stack/avct/avct_api.c"
|
||||
@@ -283,141 +268,11 @@ if(CONFIG_BT_ENABLED)
|
||||
"bluedroid/stack/smp/smp_l2c.c"
|
||||
"bluedroid/stack/smp/smp_main.c"
|
||||
"bluedroid/stack/smp/smp_utils.c")
|
||||
|
||||
if(CONFIG_BLE_MESH)
|
||||
list(APPEND COMPONENT_SRCS "esp_ble_mesh/mesh_core/bluedroid_host/mesh_bearer_adapt.c")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(CONFIG_BLE_MESH)
|
||||
list(APPEND COMPONENT_ADD_INCLUDEDIRS
|
||||
"esp_ble_mesh/mesh_common/include"
|
||||
"esp_ble_mesh/mesh_common/tinycrypt/include"
|
||||
"esp_ble_mesh/mesh_core"
|
||||
"esp_ble_mesh/mesh_core/include"
|
||||
"esp_ble_mesh/mesh_core/storage"
|
||||
"esp_ble_mesh/btc/include"
|
||||
"esp_ble_mesh/mesh_models/common/include"
|
||||
"esp_ble_mesh/mesh_models/client/include"
|
||||
"esp_ble_mesh/mesh_models/server/include"
|
||||
"esp_ble_mesh/api/core/include"
|
||||
"esp_ble_mesh/api/models/include"
|
||||
"esp_ble_mesh/api")
|
||||
|
||||
list(APPEND COMPONENT_SRCS
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_ble_api.c"
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_common_api.c"
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_local_data_operation_api.c"
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_low_power_api.c"
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_networking_api.c"
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_provisioning_api.c"
|
||||
"esp_ble_mesh/api/core/esp_ble_mesh_proxy_api.c"
|
||||
"esp_ble_mesh/api/models/esp_ble_mesh_config_model_api.c"
|
||||
"esp_ble_mesh/api/models/esp_ble_mesh_generic_model_api.c"
|
||||
"esp_ble_mesh/api/models/esp_ble_mesh_health_model_api.c"
|
||||
"esp_ble_mesh/api/models/esp_ble_mesh_lighting_model_api.c"
|
||||
"esp_ble_mesh/api/models/esp_ble_mesh_sensor_model_api.c"
|
||||
"esp_ble_mesh/api/models/esp_ble_mesh_time_scene_model_api.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_config_model.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_generic_model.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_health_model.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_lighting_model.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_prov.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_sensor_model.c"
|
||||
"esp_ble_mesh/btc/btc_ble_mesh_time_scene_model.c"
|
||||
"esp_ble_mesh/mesh_common/tinycrypt/src/aes_decrypt.c"
|
||||
"esp_ble_mesh/mesh_common/tinycrypt/src/aes_encrypt.c"
|
||||
"esp_ble_mesh/mesh_common/tinycrypt/src/cbc_mode.c"
|
||||
"esp_ble_mesh/mesh_common/tinycrypt/src/ccm_mode.c"
|
||||
"esp_ble_mesh/mesh_common/tinycrypt/src/cmac_mode.c"
|
||||
"esp_ble_mesh/mesh_common/tinycrypt/src/ctr_mode.c"
|
||||
"esp_ble_mesh/mesh_common/tinycrypt/src/ctr_prng.c"
|
||||
"esp_ble_mesh/mesh_common/tinycrypt/src/ecc_dh.c"
|
||||
"esp_ble_mesh/mesh_common/tinycrypt/src/ecc_dsa.c"
|
||||
"esp_ble_mesh/mesh_common/tinycrypt/src/ecc_platform_specific.c"
|
||||
"esp_ble_mesh/mesh_common/tinycrypt/src/ecc.c"
|
||||
"esp_ble_mesh/mesh_common/tinycrypt/src/hmac_prng.c"
|
||||
"esp_ble_mesh/mesh_common/tinycrypt/src/hmac.c"
|
||||
"esp_ble_mesh/mesh_common/tinycrypt/src/sha256.c"
|
||||
"esp_ble_mesh/mesh_common/tinycrypt/src/utils.c"
|
||||
"esp_ble_mesh/mesh_common/mesh_atomic.c"
|
||||
"esp_ble_mesh/mesh_common/mesh_buf.c"
|
||||
"esp_ble_mesh/mesh_common/mesh_common.c"
|
||||
"esp_ble_mesh/mesh_common/mesh_kernel.c"
|
||||
"esp_ble_mesh/mesh_common/mesh_mutex.c"
|
||||
"esp_ble_mesh/mesh_common/mesh_timer.c"
|
||||
"esp_ble_mesh/mesh_common/mesh_util.c"
|
||||
"esp_ble_mesh/mesh_core/storage/settings_nvs.c"
|
||||
"esp_ble_mesh/mesh_core/access.c"
|
||||
"esp_ble_mesh/mesh_core/adv.c"
|
||||
"esp_ble_mesh/mesh_core/beacon.c"
|
||||
"esp_ble_mesh/mesh_core/cfg_cli.c"
|
||||
"esp_ble_mesh/mesh_core/cfg_srv.c"
|
||||
"esp_ble_mesh/mesh_core/crypto.c"
|
||||
"esp_ble_mesh/mesh_core/fast_prov.c"
|
||||
"esp_ble_mesh/mesh_core/friend.c"
|
||||
"esp_ble_mesh/mesh_core/health_cli.c"
|
||||
"esp_ble_mesh/mesh_core/health_srv.c"
|
||||
"esp_ble_mesh/mesh_core/local_operation.c"
|
||||
"esp_ble_mesh/mesh_core/lpn.c"
|
||||
"esp_ble_mesh/mesh_core/main.c"
|
||||
"esp_ble_mesh/mesh_core/net.c"
|
||||
"esp_ble_mesh/mesh_core/prov.c"
|
||||
"esp_ble_mesh/mesh_core/provisioner_main.c"
|
||||
"esp_ble_mesh/mesh_core/provisioner_prov.c"
|
||||
"esp_ble_mesh/mesh_core/proxy_client.c"
|
||||
"esp_ble_mesh/mesh_core/proxy_server.c"
|
||||
"esp_ble_mesh/mesh_core/settings.c"
|
||||
"esp_ble_mesh/mesh_core/test.c"
|
||||
"esp_ble_mesh/mesh_core/transport.c"
|
||||
"esp_ble_mesh/mesh_models/client/client_common.c"
|
||||
"esp_ble_mesh/mesh_models/client/generic_client.c"
|
||||
"esp_ble_mesh/mesh_models/client/lighting_client.c"
|
||||
"esp_ble_mesh/mesh_models/client/sensor_client.c"
|
||||
"esp_ble_mesh/mesh_models/client/time_scene_client.c"
|
||||
"esp_ble_mesh/mesh_models/server/device_property.c"
|
||||
"esp_ble_mesh/mesh_models/server/generic_server.c"
|
||||
"esp_ble_mesh/mesh_models/server/lighting_server.c"
|
||||
"esp_ble_mesh/mesh_models/server/sensor_server.c"
|
||||
"esp_ble_mesh/mesh_models/server/server_common.c"
|
||||
"esp_ble_mesh/mesh_models/server/state_binding.c"
|
||||
"esp_ble_mesh/mesh_models/server/state_transition.c"
|
||||
"esp_ble_mesh/mesh_models/server/time_scene_server.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_NIMBLE_ENABLED)
|
||||
|
||||
if (CONFIG_BLE_MESH)
|
||||
list(APPEND COMPONENT_PRIV_INCLUDEDIRS
|
||||
common/btc/include
|
||||
common/include)
|
||||
|
||||
list(APPEND COMPONENT_ADD_INCLUDEDIRS common/osi/include)
|
||||
|
||||
list(APPEND COMPONENT_SRCS "esp_ble_mesh/mesh_core/nimble_host/mesh_bearer_adapt.c"
|
||||
"common/btc/core/btc_alarm.c"
|
||||
"common/btc/core/btc_manage.c"
|
||||
"common/btc/core/btc_task.c"
|
||||
"common/osi/alarm.c"
|
||||
"common/osi/allocator.c"
|
||||
"common/osi/buffer.c"
|
||||
"common/osi/config.c"
|
||||
"common/osi/fixed_queue.c"
|
||||
"common/osi/future.c"
|
||||
"common/osi/hash_functions.c"
|
||||
"common/osi/hash_map.c"
|
||||
"common/osi/list.c"
|
||||
"common/osi/mutex.c"
|
||||
"common/osi/osi.c"
|
||||
"common/osi/semaphore.c")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# requirements can't depend on config
|
||||
set(COMPONENT_PRIV_REQUIRES nvs_flash nimble)
|
||||
set(COMPONENT_PRIV_REQUIRES nvs_flash)
|
||||
|
||||
register_component()
|
||||
|
||||
@@ -426,6 +281,6 @@ if(CONFIG_BT_ENABLED)
|
||||
component_compile_options(-Wno-implicit-fallthrough -Wno-unused-const-variable)
|
||||
endif()
|
||||
|
||||
target_link_libraries(${COMPONENT_TARGET} "-L${CMAKE_CURRENT_LIST_DIR}/lib")
|
||||
target_link_libraries(${COMPONENT_TARGET} btdm_app)
|
||||
target_link_libraries(bt "-L${CMAKE_CURRENT_LIST_DIR}/lib")
|
||||
target_link_libraries(bt btdm_app)
|
||||
endif()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -119,7 +119,7 @@ esp_err_t esp_bluedroid_init(void)
|
||||
future_t **future_p;
|
||||
|
||||
if (esp_bt_controller_get_status() != ESP_BT_CONTROLLER_STATUS_ENABLED) {
|
||||
LOG_ERROR("Controller not initialised\n");
|
||||
LOG_ERROR("Conroller not initialised\n");
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
|
||||
@@ -665,29 +665,6 @@ esp_err_t esp_ble_get_bond_device_list(int *dev_num, esp_ble_bond_dev_t *dev_lis
|
||||
|
||||
return (ret == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
esp_err_t esp_ble_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t *TK, uint8_t len)
|
||||
{
|
||||
if(len != ESP_BT_OCTET16_LEN) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
btc_msg_t msg;
|
||||
btc_ble_gap_args_t arg;
|
||||
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_GAP_BLE;
|
||||
msg.act = BTC_GAP_BLE_OOB_REQ_REPLY_EVT;
|
||||
memcpy(arg.oob_req_reply.bd_addr, bd_addr, ESP_BD_ADDR_LEN);
|
||||
arg.oob_req_reply.len = len;
|
||||
arg.oob_req_reply.p_value = TK;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#endif /* #if (SMP_INCLUDED == TRUE) */
|
||||
|
||||
esp_err_t esp_ble_gap_disconnect(esp_bd_addr_t remote_device)
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include "esp_bt_main.h"
|
||||
#include "esp_gap_bt_api.h"
|
||||
#include "common/bt_trace.h"
|
||||
#include "bta/bta_api.h"
|
||||
#include "btc/btc_manage.h"
|
||||
#include "btc_gap_bt.h"
|
||||
#include "btc/btc_storage.h"
|
||||
|
||||
@@ -46,37 +46,4 @@ esp_err_t esp_ble_gatt_set_local_mtu (uint16_t mtu)
|
||||
arg.set_mtu.mtu = mtu;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatt_com_args_t), NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
extern uint16_t L2CA_GetFreePktBufferNum_LE(void);
|
||||
/**
|
||||
* @brief This function is called to get currently sendable packets number on controller,
|
||||
* the function is called only in BLE running core and single connection now.
|
||||
*
|
||||
* @return
|
||||
* sendable packets number on controller
|
||||
*
|
||||
*/
|
||||
|
||||
uint16_t esp_ble_get_sendable_packets_num (void)
|
||||
{
|
||||
return L2CA_GetFreePktBufferNum_LE();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is used to query the number of available buffers for the current connection.
|
||||
* When you need to query the current available buffer number, it is recommended to use this API.
|
||||
* @param[in] conn_id: current connection id.
|
||||
*
|
||||
* @return
|
||||
* Number of available buffers for the current connection
|
||||
*
|
||||
*/
|
||||
extern UINT16 L2CA_GetCurFreePktBufferNum_LE(UINT16 conn_id);
|
||||
uint16_t esp_ble_get_cur_sendable_packets_num (uint16_t connid)
|
||||
{
|
||||
return L2CA_GetCurFreePktBufferNum_LE(connid);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -431,9 +431,6 @@ esp_err_t esp_ble_gattc_write_char(esp_gatt_if_t gattc_if,
|
||||
arg.write_char.value = value;
|
||||
arg.write_char.write_type = write_type;
|
||||
arg.write_char.auth_req = auth_req;
|
||||
if(write_type == ESP_GATT_WRITE_TYPE_NO_RSP){
|
||||
l2ble_update_att_acl_pkt_num(L2CA_ADD_BTC_NUM, NULL);
|
||||
}
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), btc_gattc_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
@@ -465,10 +462,6 @@ esp_err_t esp_ble_gattc_write_char_descr (esp_gatt_if_t gattc_if,
|
||||
arg.write_descr.write_type = write_type;
|
||||
arg.write_descr.auth_req = auth_req;
|
||||
|
||||
if(write_type == ESP_GATT_WRITE_TYPE_NO_RSP){
|
||||
l2ble_update_att_acl_pkt_num(L2CA_ADD_BTC_NUM, NULL);
|
||||
}
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gattc_args_t), btc_gattc_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
|
||||
@@ -274,9 +274,6 @@ esp_err_t esp_ble_gatts_send_indicate(esp_gatt_if_t gatts_if, uint16_t conn_id,
|
||||
arg.send_ind.value_len = value_len;
|
||||
arg.send_ind.value = value;
|
||||
|
||||
if(need_confirm == false){
|
||||
l2ble_update_att_acl_pkt_num(L2CA_ADD_BTC_NUM, NULL);
|
||||
}
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gatts_args_t),
|
||||
btc_gatts_arg_deep_copy) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
||||
@@ -95,10 +95,6 @@ esp_err_t esp_spp_connect(esp_spp_sec_t sec_mask,
|
||||
btc_spp_args_t arg;
|
||||
ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED);
|
||||
|
||||
if (sec_mask != ESP_SPP_SEC_NONE && sec_mask != ESP_SPP_SEC_AUTHORIZE && sec_mask != ESP_SPP_SEC_AUTHENTICATE) {
|
||||
LOG_WARN("Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only\n");
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_SPP;
|
||||
msg.act = BTC_SPP_ACT_CONNECT;
|
||||
@@ -137,10 +133,6 @@ esp_err_t esp_spp_start_srv(esp_spp_sec_t sec_mask,
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (sec_mask != ESP_SPP_SEC_NONE && sec_mask != ESP_SPP_SEC_AUTHORIZE && sec_mask != ESP_SPP_SEC_AUTHENTICATE) {
|
||||
LOG_WARN("Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only\n");
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_SPP;
|
||||
msg.act = BTC_SPP_ACT_START_SRV;
|
||||
|
||||
@@ -83,7 +83,6 @@ typedef enum {
|
||||
ESP_BLUFI_DH_PARAM_ERROR,
|
||||
ESP_BLUFI_READ_PARAM_ERROR,
|
||||
ESP_BLUFI_MAKE_PUBLIC_ERROR,
|
||||
ESP_BLUFI_DATA_FORMAT_ERROR,
|
||||
} esp_blufi_error_state_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -54,7 +54,6 @@ typedef uint8_t esp_ble_key_type_t;
|
||||
#define ESP_LE_AUTH_NO_BOND 0x00 /*!< 0*/ /* relate to BTM_LE_AUTH_NO_BOND in stack/btm_api.h */
|
||||
#define ESP_LE_AUTH_BOND 0x01 /*!< 1 << 0 */ /* relate to BTM_LE_AUTH_BOND in stack/btm_api.h */
|
||||
#define ESP_LE_AUTH_REQ_MITM (1 << 2) /*!< 1 << 2 */ /* relate to BTM_LE_AUTH_REQ_MITM in stack/btm_api.h */
|
||||
#define ESP_LE_AUTH_REQ_BOND_MITM (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_MITM)/*!< 0101*/
|
||||
#define ESP_LE_AUTH_REQ_SC_ONLY (1 << 3) /*!< 1 << 3 */ /* relate to BTM_LE_AUTH_REQ_SC_ONLY in stack/btm_api.h */
|
||||
#define ESP_LE_AUTH_REQ_SC_BOND (ESP_LE_AUTH_BOND | ESP_LE_AUTH_REQ_SC_ONLY) /*!< 1001 */ /* relate to BTM_LE_AUTH_REQ_SC_BOND in stack/btm_api.h */
|
||||
#define ESP_LE_AUTH_REQ_SC_MITM (ESP_LE_AUTH_REQ_MITM | ESP_LE_AUTH_REQ_SC_ONLY) /*!< 1100 */ /* relate to BTM_LE_AUTH_REQ_SC_MITM in stack/btm_api.h */
|
||||
@@ -64,9 +63,6 @@ typedef uint8_t esp_ble_auth_req_t; /*!< combination of the above bit
|
||||
#define ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_DISABLE 0
|
||||
#define ESP_BLE_ONLY_ACCEPT_SPECIFIED_AUTH_ENABLE 1
|
||||
|
||||
#define ESP_BLE_OOB_DISABLE 0
|
||||
#define ESP_BLE_OOB_ENABLE 1
|
||||
|
||||
/* relate to BTM_IO_CAP_xxx in stack/btm_api.h */
|
||||
#define ESP_IO_CAP_OUT 0 /*!< DisplayOnly */ /* relate to BTM_IO_CAP_OUT in stack/btm_api.h */
|
||||
#define ESP_IO_CAP_IO 1 /*!< DisplayYesNo */ /* relate to BTM_IO_CAP_IO in stack/btm_api.h */
|
||||
@@ -267,26 +263,14 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
ESP_BLE_SM_PASSKEY = 0,
|
||||
/* Authentication requirements of local device */
|
||||
ESP_BLE_SM_AUTHEN_REQ_MODE,
|
||||
/* The IO capability of local device */
|
||||
ESP_BLE_SM_IOCAP_MODE,
|
||||
/* Initiator Key Distribution/Generation */
|
||||
ESP_BLE_SM_SET_INIT_KEY,
|
||||
/* Responder Key Distribution/Generation */
|
||||
ESP_BLE_SM_SET_RSP_KEY,
|
||||
/* Maximum Encryption key size to support */
|
||||
ESP_BLE_SM_MAX_KEY_SIZE,
|
||||
/* Minimum Encryption key size requirement from Peer */
|
||||
ESP_BLE_SM_MIN_KEY_SIZE,
|
||||
/* Set static Passkey */
|
||||
ESP_BLE_SM_SET_STATIC_PASSKEY,
|
||||
/* Reset static Passkey */
|
||||
ESP_BLE_SM_CLEAR_STATIC_PASSKEY,
|
||||
/* Accept only specified SMP Authentication requirement */
|
||||
ESP_BLE_SM_ONLY_ACCEPT_SPECIFIED_SEC_AUTH,
|
||||
/* Enable/Disable OOB support */
|
||||
ESP_BLE_SM_OOB_SUPPORT,
|
||||
ESP_BLE_SM_MAX_PARAM,
|
||||
} esp_ble_sm_param_t;
|
||||
|
||||
@@ -600,7 +584,7 @@ typedef enum {
|
||||
typedef enum {
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_ADV_ADDR = 0, /*!< BLE advertising address , device info will be added into ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_ADDR_LIST */
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_LINK_ID, /*!< BLE mesh link ID, it is for BLE mesh, device info will be added into ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_MESH_LINK_ID_LIST */
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_BEACON_TYPE, /*!< BLE mesh beacon AD type, the format is | Len | 0x2B | Beacon Type | Beacon Data | */
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_BEACON_TYPE, /*!< BLE mesh beacon AD type, the format is | Len | 0x2B | Beacon Type | Beacon Data | */
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_PROV_SRV_ADV, /*!< BLE mesh provisioning service uuid, the format is | 0x02 | 0x01 | flags | 0x03 | 0x03 | 0x1827 | .... |` */
|
||||
ESP_BLE_DUPLICATE_SCAN_EXCEPTIONAL_INFO_MESH_PROXY_SRV_ADV, /*!< BLE mesh adv with proxy service uuid, the format is | 0x02 | 0x01 | flags | 0x03 | 0x03 | 0x1828 | .... |` */
|
||||
} esp_ble_duplicate_exceptional_info_type_t;
|
||||
@@ -1161,7 +1145,7 @@ esp_err_t esp_ble_passkey_reply(esp_bd_addr_t bd_addr, bool accept, uint32_t pas
|
||||
|
||||
|
||||
/**
|
||||
* @brief Reply the confirm value to the peer device in the secure connection stage.
|
||||
* @brief Reply the confirm value to the peer device in the legacy connection stage.
|
||||
*
|
||||
* @param[in] bd_addr : BD address of the peer device
|
||||
* @param[in] accept : numbers to compare are the same or different.
|
||||
@@ -1210,20 +1194,6 @@ int esp_ble_get_bond_device_num(void);
|
||||
*/
|
||||
esp_err_t esp_ble_get_bond_device_list(int *dev_num, esp_ble_bond_dev_t *dev_list);
|
||||
|
||||
/**
|
||||
* @brief This function is called to provide the OOB data for
|
||||
* SMP in response to ESP_GAP_BLE_OOB_REQ_EVT
|
||||
*
|
||||
* @param[in] bd_addr: BD address of the peer device.
|
||||
* @param[in] TK: TK value, the TK value shall be a 128-bit random number
|
||||
* @param[in] len: length of tk, should always be 128-bit
|
||||
*
|
||||
* @return - ESP_OK : success
|
||||
* - other : failed
|
||||
*
|
||||
*/
|
||||
esp_err_t esp_ble_oob_req_reply(esp_bd_addr_t bd_addr, uint8_t *TK, uint8_t len);
|
||||
|
||||
#endif /* #if (SMP_INCLUDED == TRUE) */
|
||||
|
||||
/**
|
||||
|
||||
@@ -361,15 +361,13 @@ esp_err_t esp_bt_gap_register_callback(esp_bt_gap_cb_t callback);
|
||||
esp_err_t esp_bt_gap_set_scan_mode(esp_bt_scan_mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief This function starts Inquiry and Name Discovery. It should be called after esp_bluedroid_enable() completes successfully.
|
||||
* When Inquiry is halted and cached results do not contain device name, then Name Discovery will connect to the peer target to get the device name.
|
||||
* esp_bt_gap_cb_t will be called with ESP_BT_GAP_DISC_STATE_CHANGED_EVT when Inquriry is started or Name Discovery is completed.
|
||||
* esp_bt_gap_cb_t will be called with ESP_BT_GAP_DISC_RES_EVT each time the two types of discovery results are got.
|
||||
* @brief Start device discovery. This function should be called after esp_bluedroid_enable() completes successfully.
|
||||
* esp_bt_gap_cb_t will is called with ESP_BT_GAP_DISC_STATE_CHANGED_EVT if discovery is started or halted.
|
||||
* esp_bt_gap_cb_t will is called with ESP_BT_GAP_DISC_RES_EVT if discovery result is got.
|
||||
*
|
||||
* @param[in] mode - Inquiry mode
|
||||
* @param[in] inq_len - Inquiry duration in 1.28 sec units, ranging from 0x01 to 0x30. This parameter only specifies the total duration of the Inquiry process,
|
||||
* - when this time expires, Inquiry will be halted.
|
||||
* @param[in] num_rsps - Number of responses that can be received before the Inquiry is halted, value 0 indicates an unlimited number of responses.
|
||||
* @param[in] mode - inquiry mode
|
||||
* @param[in] inq_len - inquiry duration in 1.28 sec units, ranging from 0x01 to 0x30
|
||||
* @param[in] num_rsps - number of inquiry responses that can be received, value 0 indicates an unlimited number of responses
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Succeed
|
||||
@@ -380,9 +378,8 @@ esp_err_t esp_bt_gap_set_scan_mode(esp_bt_scan_mode_t mode);
|
||||
esp_err_t esp_bt_gap_start_discovery(esp_bt_inq_mode_t mode, uint8_t inq_len, uint8_t num_rsps);
|
||||
|
||||
/**
|
||||
* @brief Cancel Inquiry and Name Discovery. This function should be called after esp_bluedroid_enable() completes successfully.
|
||||
* esp_bt_gap_cb_t will be called with ESP_BT_GAP_DISC_STATE_CHANGED_EVT if Inquiry or Name Discovery is cancelled by
|
||||
* calling this function.
|
||||
* @brief Cancel device discovery. This function should be called after esp_bluedroid_enable() completes successfully
|
||||
* esp_bt_gap_cb_t will is called with ESP_BT_GAP_DISC_STATE_CHANGED_EVT if discovery is stopped.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : Succeed
|
||||
|
||||
@@ -44,11 +44,6 @@ extern "C" {
|
||||
*/
|
||||
extern esp_err_t esp_ble_gatt_set_local_mtu (uint16_t mtu);
|
||||
|
||||
#if (BLE_INCLUDED == TRUE)
|
||||
extern uint16_t esp_ble_get_sendable_packets_num (void);
|
||||
extern uint16_t esp_ble_get_cur_sendable_packets_num (uint16_t connid);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -34,7 +34,7 @@ extern "C" {
|
||||
* All "ESP_GATT_UUID_xxx" is attribute types
|
||||
*/
|
||||
#define ESP_GATT_UUID_IMMEDIATE_ALERT_SVC 0x1802 /* Immediate alert Service*/
|
||||
#define ESP_GATT_UUID_LINK_LOSS_SVC 0x1803 /* Link Loss Service*/
|
||||
#define ESP_GATT_UUID_LINK_LOSS_SVC 0x1803 /* Link Loss Service*/
|
||||
#define ESP_GATT_UUID_TX_POWER_SVC 0x1804 /* TX Power Service*/
|
||||
#define ESP_GATT_UUID_CURRENT_TIME_SVC 0x1805 /* Current Time Service Service*/
|
||||
#define ESP_GATT_UUID_REF_TIME_UPDATE_SVC 0x1806 /* Reference Time Update Service*/
|
||||
@@ -68,14 +68,8 @@ extern "C" {
|
||||
#define ESP_GATT_UUID_CHAR_PRESENT_FORMAT 0x2904 /* Characteristic Presentation Format*/
|
||||
#define ESP_GATT_UUID_CHAR_AGG_FORMAT 0x2905 /* Characteristic Aggregate Format*/
|
||||
#define ESP_GATT_UUID_CHAR_VALID_RANGE 0x2906 /* Characteristic Valid Range */
|
||||
#define ESP_GATT_UUID_EXT_RPT_REF_DESCR 0x2907 /* External Report Reference */
|
||||
#define ESP_GATT_UUID_RPT_REF_DESCR 0x2908 /* Report Reference */
|
||||
#define ESP_GATT_UUID_NUM_DIGITALS_DESCR 0x2909 /* Number of Digitals */
|
||||
#define ESP_GATT_UUID_VALUE_TRIGGER_DESCR 0x290A /* Value Trigger Setting */
|
||||
#define ESP_GATT_UUID_ENV_SENSING_CONFIG_DESCR 0x290B /* Environmental Sensing Configuration */
|
||||
#define ESP_GATT_UUID_ENV_SENSING_MEASUREMENT_DESCR 0x290C /* Environmental Sensing Measurement */
|
||||
#define ESP_GATT_UUID_ENV_SENSING_TRIGGER_DESCR 0x290D /* Environmental Sensing Trigger Setting */
|
||||
#define ESP_GATT_UUID_TIME_TRIGGER_DESCR 0x290E /* Time Trigger Setting */
|
||||
#define ESP_GATT_UUID_EXT_RPT_REF_DESCR 0x2907
|
||||
#define ESP_GATT_UUID_RPT_REF_DESCR 0x2908
|
||||
|
||||
/* GAP Profile Attributes */
|
||||
#define ESP_GATT_UUID_GAP_DEVICE_NAME 0x2A00
|
||||
@@ -305,7 +299,7 @@ typedef enum {
|
||||
* @brief Attribute description (used to create database)
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
{
|
||||
uint16_t uuid_length; /*!< UUID length */
|
||||
uint8_t *uuid_p; /*!< UUID value */
|
||||
uint16_t perm; /*!< Attribute permission */
|
||||
@@ -354,23 +348,23 @@ typedef struct
|
||||
/**
|
||||
* @brief Gatt include service entry element
|
||||
*/
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
uint16_t start_hdl; /*!< Gatt start handle value of included service */
|
||||
uint16_t end_hdl; /*!< Gatt end handle value of included service */
|
||||
uint16_t uuid; /*!< Gatt attribute value UUID of included service */
|
||||
uint16_t start_hdl; /*!< Gatt start handle value of included service */
|
||||
uint16_t end_hdl; /*!< Gatt end handle value of included service */
|
||||
uint16_t uuid; /*!< Gatt attribute value UUID of included service */
|
||||
} esp_gatts_incl_svc_desc_t; /*!< Gatt include service entry element */
|
||||
|
||||
/**
|
||||
* @brief Gatt include 128 bit service entry element
|
||||
*/
|
||||
typedef struct
|
||||
typedef struct
|
||||
{
|
||||
uint16_t start_hdl; /*!< Gatt start handle value of included 128 bit service */
|
||||
uint16_t end_hdl; /*!< Gatt end handle value of included 128 bit service */
|
||||
} esp_gatts_incl128_svc_desc_t; /*!< Gatt include 128 bit service entry element */
|
||||
uint16_t start_hdl; /*!< Gatt start handle value of included 128 bit service */
|
||||
uint16_t end_hdl; /*!< Gatt end handle value of included 128 bit service */
|
||||
} esp_gatts_incl128_svc_desc_t; /*!< Gatt include 128 bit service entry element */
|
||||
|
||||
/// Gatt attribute value
|
||||
/// Gatt attribute value
|
||||
typedef struct {
|
||||
uint8_t value[ESP_GATT_MAX_ATTR_LEN]; /*!< Gatt attribute value */
|
||||
uint16_t handle; /*!< Gatt attribute handle */
|
||||
@@ -432,8 +426,8 @@ typedef struct {
|
||||
/**
|
||||
* @brief service element
|
||||
*/
|
||||
typedef struct {
|
||||
bool is_primary; /*!< The service flag, true if the service is primary service, else is secondary service */
|
||||
typedef struct {
|
||||
bool is_primary; /*!< The service flag, true if the service is primary service, else is secondly service */
|
||||
uint16_t start_handle; /*!< The start handle of the service */
|
||||
uint16_t end_handle; /*!< The end handle of the service */
|
||||
esp_bt_uuid_t uuid; /*!< The uuid of the service */
|
||||
|
||||
@@ -30,7 +30,7 @@ typedef enum {
|
||||
ESP_SPP_NO_RESOURCE /*!< No more set pm control block */
|
||||
} esp_spp_status_t;
|
||||
|
||||
/* Security Setting Mask, Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only.*/
|
||||
/* Security Setting Mask */
|
||||
#define ESP_SPP_SEC_NONE 0x0000 /*!< No security. relate to BTA_SEC_NONE in bta/bta_api.h */
|
||||
#define ESP_SPP_SEC_AUTHORIZE 0x0001 /*!< Authorization required (only needed for out going connection ) relate to BTA_SEC_AUTHORIZE in bta/bta_api.h*/
|
||||
#define ESP_SPP_SEC_AUTHENTICATE 0x0012 /*!< Authentication required. relate to BTA_SEC_AUTHENTICATE in bta/bta_api.h*/
|
||||
@@ -229,7 +229,7 @@ esp_err_t esp_spp_start_discovery(esp_bd_addr_t bd_addr);
|
||||
* When the connection is established or failed,
|
||||
* the callback is called with ESP_SPP_OPEN_EVT.
|
||||
*
|
||||
* @param[in] sec_mask: Security Setting Mask. Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only.
|
||||
* @param[in] sec_mask: Security Setting Mask .
|
||||
* @param[in] role: Master or slave.
|
||||
* @param[in] remote_scn: Remote device bluetooth device SCN.
|
||||
* @param[in] peer_bd_addr: Remote device bluetooth device address.
|
||||
@@ -260,7 +260,7 @@ esp_err_t esp_spp_disconnect(uint32_t handle);
|
||||
* When the connection is established, the callback is called
|
||||
* with ESP_SPP_SRV_OPEN_EVT.
|
||||
*
|
||||
* @param[in] sec_mask: Security Setting Mask. Security Setting Mask. Suggest to use ESP_SPP_SEC_NONE, ESP_SPP_SEC_AUTHORIZE or ESP_SPP_SEC_AUTHENTICATE only.
|
||||
* @param[in] sec_mask: Security Setting Mask .
|
||||
* @param[in] role: Master or slave.
|
||||
* @param[in] local_scn: The specific channel you want to get.
|
||||
* If channel is 0, means get any channel.
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
|
||||
#include "bta/bta_ar_api.h"
|
||||
#endif
|
||||
#include "bta/bta_api.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
@@ -529,21 +528,8 @@ static void bta_av_proc_stream_evt(UINT8 handle, BD_ADDR bd_addr, UINT8 event, t
|
||||
/* look up application event */
|
||||
if ((p_data == NULL) || (p_data->hdr.err_code == 0)) {
|
||||
p_msg->hdr.event = bta_av_stream_evt_ok[event];
|
||||
if (p_msg->hdr.event == BTA_AV_STR_START_OK_EVT) {
|
||||
BTA_DmCoexEventTrigger(BTA_COEX_EVT_STREAMING_STARTED);
|
||||
} else if (p_msg->hdr.event == BTA_AV_STR_START_FAIL_EVT ||
|
||||
p_msg->hdr.event == BTA_AV_STR_SUSPEND_CFM_EVT ||
|
||||
p_msg->hdr.event == BTA_AV_STR_CLOSE_EVT) {
|
||||
BTA_DmCoexEventTrigger(BTA_COEX_EVT_STREAMING_STOPPED);
|
||||
}
|
||||
} else {
|
||||
p_msg->hdr.event = bta_av_stream_evt_fail[event];
|
||||
if (p_msg->hdr.event == BTA_AV_STR_START_FAIL_EVT ||
|
||||
p_msg->hdr.event == BTA_AV_STR_START_OK_EVT ||
|
||||
p_msg->hdr.event == BTA_AV_STR_SUSPEND_CFM_EVT ||
|
||||
p_msg->hdr.event == BTA_AV_STR_CLOSE_EVT) {
|
||||
BTA_DmCoexEventTrigger(BTA_COEX_EVT_STREAMING_STOPPED);
|
||||
}
|
||||
}
|
||||
|
||||
p_msg->initiator = FALSE;
|
||||
|
||||
@@ -114,7 +114,7 @@ void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name, UINT8 app_id,
|
||||
p_buf->hdr.layer_specific = chnl;
|
||||
p_buf->hdr.event = BTA_AV_API_REGISTER_EVT;
|
||||
if (p_service_name) {
|
||||
BCM_STRNCPY_S(p_buf->p_service_name, p_service_name, BTA_SERVICE_NAME_LEN);
|
||||
BCM_STRNCPY_S(p_buf->p_service_name, sizeof(p_buf->p_service_name), p_service_name, BTA_SERVICE_NAME_LEN);
|
||||
p_buf->p_service_name[BTA_SERVICE_NAME_LEN - 1] = 0;
|
||||
} else {
|
||||
p_buf->p_service_name[0] = 0;
|
||||
|
||||
@@ -40,9 +40,8 @@ const UINT32 bta_av_meta_caps_co_ids[] = {
|
||||
AVRC_CO_BROADCOM
|
||||
};
|
||||
|
||||
/* AVRCP supported categories */
|
||||
#define BTA_AV_RC_SNK_SUPF_CT (AVRC_SUPF_CT_CAT1)
|
||||
#define BTA_AV_RC_SRC_SUPF_CT (AVRC_SUPF_CT_CAT2)
|
||||
/* AVRCP cupported categories */
|
||||
#define BTA_AV_RC_SUPF_CT (AVRC_SUPF_CT_CAT2)
|
||||
|
||||
/* Added to modify
|
||||
** 1. flush timeout
|
||||
@@ -63,11 +62,9 @@ const UINT16 bta_av_audio_flush_to[] = {
|
||||
/* Note: Android doesnt support AVRC_SUPF_TG_GROUP_NAVI */
|
||||
/* Note: if AVRC_SUPF_TG_GROUP_NAVI is set, bta_av_cfg.avrc_group should be TRUE */
|
||||
#if AVRC_METADATA_INCLUDED == TRUE
|
||||
#define BTA_AV_RC_SNK_SUPF_TG (AVRC_SUPF_TG_CAT2) /* TODO: | AVRC_SUPF_TG_APP_SETTINGS) */
|
||||
#define BTA_AV_RC_SRC_SUPF_TG (AVRC_SUPF_TG_CAT1) /* TODO: | AVRC_SUPF_TG_APP_SETTINGS) */
|
||||
#define BTA_AV_RC_SUPF_TG (AVRC_SUPF_TG_CAT1) /* TODO: | AVRC_SUPF_TG_APP_SETTINGS) */
|
||||
#else
|
||||
#define BTA_AV_RC_SNK_SUPF_TG (AVRC_SUPF_TG_CAT2)
|
||||
#define BTA_AV_RC_SRC_SUPF_TG (AVRC_SUPF_TG_CAT1)
|
||||
#define BTA_AV_RC_SUPF_TG (AVRC_SUPF_TG_CAT1)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -98,10 +95,8 @@ const tBTA_AV_CFG bta_av_cfg = {
|
||||
48, /* AVRCP MTU at L2CAP for control channel */
|
||||
#endif
|
||||
BTA_AV_MAX_RC_BR_MTU, /* AVRCP MTU at L2CAP for browsing channel */
|
||||
BTA_AV_RC_SNK_SUPF_CT, /* AVRCP controller categories as SNK */
|
||||
BTA_AV_RC_SNK_SUPF_TG, /* AVRCP target categories as SNK */
|
||||
BTA_AV_RC_SRC_SUPF_CT, /* AVRCP controller categories as SRC */
|
||||
BTA_AV_RC_SRC_SUPF_TG, /* AVRCP target categories as SRC */
|
||||
BTA_AV_RC_SUPF_CT, /* AVRCP controller categories */
|
||||
BTA_AV_RC_SUPF_TG, /* AVRCP target categories */
|
||||
672, /* AVDTP signaling channel MTU at L2CAP */
|
||||
BTA_AV_MAX_A2DP_MTU, /* AVDTP audio transport channel MTU at L2CAP */
|
||||
bta_av_audio_flush_to, /* AVDTP audio transport channel flush timeout */
|
||||
|
||||
@@ -483,7 +483,8 @@ static void bta_av_api_sink_enable(tBTA_AV_DATA *p_data)
|
||||
activate_sink = p_data->hdr.layer_specific;
|
||||
APPL_TRACE_DEBUG("bta_av_api_sink_enable %d \n", activate_sink)
|
||||
char p_service_name[BTA_SERVICE_NAME_LEN + 1];
|
||||
BCM_STRNCPY_S(p_service_name, BTIF_AVK_SERVICE_NAME, BTA_SERVICE_NAME_LEN);
|
||||
BCM_STRNCPY_S(p_service_name, sizeof(p_service_name),
|
||||
BTIF_AVK_SERVICE_NAME, BTA_SERVICE_NAME_LEN);
|
||||
|
||||
if (activate_sink) {
|
||||
AVDT_SINK_Activate();
|
||||
@@ -525,7 +526,7 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
|
||||
tBTA_UTL_COD cod;
|
||||
UINT8 index = 0;
|
||||
char p_avk_service_name[BTA_SERVICE_NAME_LEN + 1];
|
||||
BCM_STRNCPY_S(p_avk_service_name, BTIF_AVK_SERVICE_NAME, BTA_SERVICE_NAME_LEN);
|
||||
BCM_STRNCPY_S(p_avk_service_name, sizeof(p_avk_service_name), BTIF_AVK_SERVICE_NAME, BTA_SERVICE_NAME_LEN);
|
||||
|
||||
memset(&cs, 0, sizeof(tAVDT_CS));
|
||||
|
||||
@@ -570,13 +571,9 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
|
||||
bta_ar_reg_avct(p_bta_av_cfg->avrc_mtu, p_bta_av_cfg->avrc_br_mtu,
|
||||
(UINT8)(bta_av_cb.sec_mask & (~BTA_SEC_AUTHORIZE)), BTA_ID_AV);
|
||||
#endif
|
||||
if (p_data->api_reg.tsep == AVDT_TSEP_SRC) {
|
||||
bta_ar_reg_avrc(UUID_SERVCLASS_AV_REM_CTRL_TARGET, "AV Remote Control Target\n", NULL,
|
||||
p_bta_av_cfg->avrc_src_tg_cat, BTA_ID_AV);
|
||||
} else {
|
||||
bta_ar_reg_avrc(UUID_SERVCLASS_AV_REM_CTRL_TARGET, "AV Remote Control Target\n", NULL,
|
||||
p_bta_av_cfg->avrc_snk_tg_cat, BTA_ID_AV);
|
||||
}
|
||||
|
||||
bta_ar_reg_avrc(UUID_SERVCLASS_AV_REM_CTRL_TARGET, "AV Remote Control Target\n", NULL,
|
||||
p_bta_av_cfg->avrc_tg_cat, BTA_ID_AV);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -710,13 +707,8 @@ static void bta_av_api_register(tBTA_AV_DATA *p_data)
|
||||
}
|
||||
#if( defined BTA_AR_INCLUDED ) && (BTA_AR_INCLUDED == TRUE)
|
||||
/* create an SDP record as AVRC CT. */
|
||||
if (p_data->api_reg.tsep == AVDT_TSEP_SRC) {
|
||||
bta_ar_reg_avrc(UUID_SERVCLASS_AV_REMOTE_CONTROL, "AV Remote Control Controller\n", NULL,
|
||||
p_bta_av_cfg->avrc_src_ct_cat, BTA_ID_AV);
|
||||
} else {
|
||||
bta_ar_reg_avrc(UUID_SERVCLASS_AV_REMOTE_CONTROL, "AV Remote Control Controller\n", NULL,
|
||||
p_bta_av_cfg->avrc_snk_ct_cat, BTA_ID_AV);
|
||||
}
|
||||
bta_ar_reg_avrc(UUID_SERVCLASS_AV_REMOTE_CONTROL, NULL, NULL,
|
||||
p_bta_av_cfg->avrc_ct_cat, BTA_ID_AV);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ static void bta_dm_sdp_callback (UINT16 sdp_status);
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, UINT8 *service_name, UINT8 service_id, BOOLEAN is_originator);
|
||||
static UINT8 bta_dm_pin_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, BOOLEAN min_16_digit);
|
||||
static UINT8 bta_dm_new_link_key_cback(BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, LINK_KEY key, UINT8 key_type, BOOLEAN sc_support);
|
||||
static UINT8 bta_dm_new_link_key_cback(BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, LINK_KEY key, UINT8 key_type);
|
||||
static UINT8 bta_dm_authentication_complete_cback(BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_name, int result);
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
static void bta_dm_local_name_cback(BD_ADDR bd_addr);
|
||||
@@ -323,9 +323,6 @@ void bta_dm_deinit_cb(void)
|
||||
}
|
||||
#endif
|
||||
memset(&bta_dm_cb, 0, sizeof(bta_dm_cb));
|
||||
#if BTA_DYNAMIC_MEMORY
|
||||
xSemaphoreGive(deinit_semaphore);
|
||||
#endif /* #if BTA_DYNAMIC_MEMORY */
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -696,6 +693,7 @@ void bta_dm_set_visibility(tBTA_DM_MSG *p_data)
|
||||
if (p_data->set_visibility.pair_mode != BTA_DM_IGNORE || p_data->set_visibility.conn_paired_only != BTA_DM_IGNORE) {
|
||||
BTM_SetPairableMode((BOOLEAN)(!(bta_dm_cb.disable_pair_mode)), bta_dm_cb.conn_paired_only);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -822,7 +820,7 @@ void bta_dm_add_device (tBTA_DM_MSG *p_data)
|
||||
|
||||
if (!BTM_SecAddDevice (p_dev->bd_addr, p_dc, p_dev->bd_name, p_dev->features,
|
||||
trusted_services_mask, p_lc, p_dev->key_type, p_dev->io_cap,
|
||||
p_dev->pin_length, p_dev->sc_support)) {
|
||||
p_dev->pin_length)) {
|
||||
APPL_TRACE_ERROR ("BTA_DM: Error adding device %08x%04x",
|
||||
(p_dev->bd_addr[0] << 24) + (p_dev->bd_addr[1] << 16) + (p_dev->bd_addr[2] << 8) + p_dev->bd_addr[3],
|
||||
(p_dev->bd_addr[4] << 8) + p_dev->bd_addr[5]);
|
||||
@@ -1157,21 +1155,6 @@ void bta_dm_loc_oob(tBTA_DM_MSG *p_data)
|
||||
BTM_ReadLocalOobData();
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_oob_reply
|
||||
**
|
||||
** Description This function is called to provide the OOB data for
|
||||
** SMP in response to BLE OOB request.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_dm_oob_reply(tBTA_DM_MSG *p_data)
|
||||
{
|
||||
BTM_BleOobDataReply(p_data->oob_reply.bd_addr, BTM_SUCCESS, p_data->oob_reply.len, p_data->oob_reply.value);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_ci_io_req_act
|
||||
@@ -1686,7 +1669,7 @@ void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
|
||||
if (SDP_FindServiceUUIDInRec(p_sdp_rec, &service_uuid)) {
|
||||
/* send result back to app now, one by one */
|
||||
bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
|
||||
BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name, bta_dm_get_remname(), (BD_NAME_LEN));
|
||||
BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name, sizeof(BD_NAME), bta_dm_get_remname(), (BD_NAME_LEN));
|
||||
result.disc_ble_res.bd_name[BD_NAME_LEN] = 0;
|
||||
result.disc_ble_res.service.len = service_uuid.len;
|
||||
result.disc_ble_res.service.uu.uuid16 = service_uuid.uu.uuid16;
|
||||
@@ -1827,7 +1810,8 @@ void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
|
||||
|
||||
}
|
||||
bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
|
||||
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, bta_dm_get_remname(), (BD_NAME_LEN - 1));
|
||||
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
|
||||
bta_dm_get_remname(), (BD_NAME_LEN - 1));
|
||||
|
||||
/* make sure the string is null terminated */
|
||||
p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
|
||||
@@ -1853,7 +1837,8 @@ void bta_dm_sdp_result (tBTA_DM_MSG *p_data)
|
||||
p_msg->disc_result.result.disc_res.result = BTA_FAILURE;
|
||||
p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
|
||||
bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
|
||||
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, bta_dm_get_remname(), (BD_NAME_LEN - 1));
|
||||
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
|
||||
bta_dm_get_remname(), (BD_NAME_LEN - 1));
|
||||
|
||||
/* make sure the string is null terminated */
|
||||
p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
|
||||
@@ -2237,7 +2222,8 @@ static void bta_dm_find_services ( BD_ADDR bd_addr)
|
||||
p_msg->hdr.event = BTA_DM_DISCOVERY_RESULT_EVT;
|
||||
p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
|
||||
bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
|
||||
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, bta_dm_get_remname(), (BD_NAME_LEN - 1));
|
||||
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
|
||||
bta_dm_get_remname(), (BD_NAME_LEN - 1));
|
||||
|
||||
/* make sure the string is terminated */
|
||||
p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
|
||||
@@ -2422,7 +2408,8 @@ static void bta_dm_discover_device(BD_ADDR remote_bd_addr)
|
||||
p_msg->disc_result.result.disc_res.result = BTA_SUCCESS;
|
||||
p_msg->disc_result.result.disc_res.services = bta_dm_search_cb.services_found;
|
||||
bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
|
||||
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, (char *)bta_dm_search_cb.peer_name, (BD_NAME_LEN - 1));
|
||||
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
|
||||
(char *)bta_dm_search_cb.peer_name, (BD_NAME_LEN - 1));
|
||||
|
||||
/* make sure the string is terminated */
|
||||
p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
|
||||
@@ -2566,7 +2553,7 @@ static void bta_dm_service_search_remname_cback (BD_ADDR bd_addr, DEV_CLASS dc,
|
||||
rem_name.length = (BD_NAME_LEN - 1);
|
||||
rem_name.remote_bd_name[(BD_NAME_LEN - 1)] = 0;
|
||||
}
|
||||
BCM_STRNCPY_S((char *)rem_name.remote_bd_name, (char *)bd_name, (BD_NAME_LEN - 1));
|
||||
BCM_STRNCPY_S((char *)rem_name.remote_bd_name, sizeof(BD_NAME), (char *)bd_name, (BD_NAME_LEN - 1));
|
||||
rem_name.status = BTM_SUCCESS;
|
||||
|
||||
bta_dm_remname_cback(&rem_name);
|
||||
@@ -2609,7 +2596,7 @@ static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name)
|
||||
|
||||
/* remote name discovery is done but it could be failed */
|
||||
bta_dm_search_cb.name_discover_done = TRUE;
|
||||
BCM_STRNCPY_S((char *)bta_dm_search_cb.peer_name,(char *)p_remote_name->remote_bd_name, (BD_NAME_LEN));
|
||||
BCM_STRNCPY_S((char *)bta_dm_search_cb.peer_name, sizeof(BD_NAME), (char *)p_remote_name->remote_bd_name, (BD_NAME_LEN));
|
||||
bta_dm_search_cb.peer_name[BD_NAME_LEN] = 0;
|
||||
|
||||
BTM_SecDeleteRmtNameNotifyCallback(&bta_dm_service_search_remname_cback);
|
||||
@@ -2622,7 +2609,7 @@ static void bta_dm_remname_cback (tBTM_REMOTE_DEV_NAME *p_remote_name)
|
||||
|
||||
if ((p_msg = (tBTA_DM_REM_NAME *) osi_malloc(sizeof(tBTA_DM_REM_NAME))) != NULL) {
|
||||
bdcpy (p_msg->result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
|
||||
BCM_STRNCPY_S((char *)p_msg->result.disc_res.bd_name, (char *)p_remote_name->remote_bd_name, (BD_NAME_LEN));
|
||||
BCM_STRNCPY_S((char *)p_msg->result.disc_res.bd_name, sizeof(BD_NAME), (char *)p_remote_name->remote_bd_name, (BD_NAME_LEN));
|
||||
|
||||
/* make sure the string is null terminated */
|
||||
p_msg->result.disc_res.bd_name[BD_NAME_LEN] = 0;
|
||||
@@ -2654,7 +2641,7 @@ static UINT8 bta_dm_authorize_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NA
|
||||
bdcpy(sec_event.authorize.bd_addr, bd_addr);
|
||||
memcpy(sec_event.authorize.dev_class, dev_class, DEV_CLASS_LEN);
|
||||
|
||||
BCM_STRNCPY_S((char *)sec_event.authorize.bd_name, (char *)bd_name, (BD_NAME_LEN - 1));
|
||||
BCM_STRNCPY_S((char *)sec_event.authorize.bd_name, sizeof(BD_NAME), (char *)bd_name, (BD_NAME_LEN - 1));
|
||||
|
||||
/* make sure the string is null terminated */
|
||||
sec_event.authorize.bd_name[BD_NAME_LEN - 1] = 0;
|
||||
@@ -2766,7 +2753,7 @@ static UINT8 bta_dm_pin_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_
|
||||
|
||||
bdcpy(sec_event.pin_req.bd_addr, bd_addr);
|
||||
BTA_COPY_DEVICE_CLASS(sec_event.pin_req.dev_class, dev_class);
|
||||
BCM_STRNCPY_S((char *)sec_event.pin_req.bd_name, (char *)bd_name, (BD_NAME_LEN - 1));
|
||||
BCM_STRNCPY_S((char *)sec_event.pin_req.bd_name, sizeof(BD_NAME), (char *)bd_name, (BD_NAME_LEN - 1));
|
||||
sec_event.pin_req.bd_name[BD_NAME_LEN - 1] = 0;
|
||||
sec_event.pin_req.min_16_digit = min_16_digit;
|
||||
|
||||
@@ -2784,8 +2771,7 @@ static UINT8 bta_dm_pin_cback (BD_ADDR bd_addr, DEV_CLASS dev_class, BD_NAME bd_
|
||||
**
|
||||
*******************************************************************************/
|
||||
static UINT8 bta_dm_new_link_key_cback(BD_ADDR bd_addr, DEV_CLASS dev_class,
|
||||
BD_NAME bd_name, LINK_KEY key, UINT8 key_type,
|
||||
BOOLEAN sc_support)
|
||||
BD_NAME bd_name, LINK_KEY key, UINT8 key_type)
|
||||
{
|
||||
tBTA_DM_SEC sec_event;
|
||||
tBTA_DM_AUTH_CMPL *p_auth_cmpl;
|
||||
@@ -2807,7 +2793,6 @@ static UINT8 bta_dm_new_link_key_cback(BD_ADDR bd_addr, DEV_CLASS dev_class,
|
||||
p_auth_cmpl->key_present = TRUE;
|
||||
p_auth_cmpl->key_type = key_type;
|
||||
p_auth_cmpl->success = TRUE;
|
||||
p_auth_cmpl->sc_support = sc_support;
|
||||
|
||||
memcpy(p_auth_cmpl->key, key, LINK_KEY_LEN);
|
||||
sec_event.auth_cmpl.fail_reason = HCI_SUCCESS;
|
||||
@@ -2938,7 +2923,8 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
|
||||
copy these values into key_notif from cfm_req */
|
||||
bdcpy(sec_event.key_notif.bd_addr, p_data->cfm_req.bd_addr);
|
||||
BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->cfm_req.dev_class);
|
||||
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, (char *)p_data->cfm_req.bd_name, (BD_NAME_LEN - 1));
|
||||
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME),
|
||||
(char *)p_data->cfm_req.bd_name, (BD_NAME_LEN - 1));
|
||||
sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
|
||||
}
|
||||
}
|
||||
@@ -2959,7 +2945,8 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
|
||||
} else {
|
||||
bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
|
||||
BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
|
||||
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, (char *)p_data->key_notif.bd_name, (BD_NAME_LEN - 1));
|
||||
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME),
|
||||
(char *)p_data->key_notif.bd_name, (BD_NAME_LEN - 1));
|
||||
sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
|
||||
}
|
||||
}
|
||||
@@ -2980,7 +2967,8 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
|
||||
} else {
|
||||
bdcpy(sec_event.key_notif.bd_addr, p_data->key_notif.bd_addr);
|
||||
BTA_COPY_DEVICE_CLASS(sec_event.key_notif.dev_class, p_data->key_notif.dev_class);
|
||||
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, (char *)p_data->key_notif.bd_name, (BD_NAME_LEN - 1));
|
||||
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME),
|
||||
(char *)p_data->key_notif.bd_name, (BD_NAME_LEN - 1));
|
||||
sec_event.key_notif.bd_name[BD_NAME_LEN - 1] = 0;
|
||||
}
|
||||
}
|
||||
@@ -3009,7 +2997,7 @@ static UINT8 bta_dm_sp_cback (tBTM_SP_EVT event, tBTM_SP_EVT_DATA *p_data)
|
||||
|
||||
bdcpy(sec_event.rmt_oob.bd_addr, p_data->rmt_oob.bd_addr);
|
||||
BTA_COPY_DEVICE_CLASS(sec_event.rmt_oob.dev_class, p_data->rmt_oob.dev_class);
|
||||
BCM_STRNCPY_S((char *)sec_event.rmt_oob.bd_name, (char *)p_data->rmt_oob.bd_name, (BD_NAME_LEN - 1));
|
||||
BCM_STRNCPY_S((char *)sec_event.rmt_oob.bd_name, sizeof(BD_NAME), (char *)p_data->rmt_oob.bd_name, (BD_NAME_LEN - 1));
|
||||
sec_event.rmt_oob.bd_name[BD_NAME_LEN - 1] = 0;
|
||||
|
||||
bta_dm_cb.p_sec_cback(BTA_DM_SP_RMT_OOB_EVT, &sec_event);
|
||||
@@ -3085,7 +3073,6 @@ static void bta_dm_bl_change_cback (tBTM_BL_EVENT_DATA *p_data)
|
||||
|
||||
switch (p_msg->event) {
|
||||
case BTM_BL_CONN_EVT:
|
||||
p_msg->sc_downgrade = p_data->conn.sc_downgrade;
|
||||
p_msg->is_new = TRUE;
|
||||
bdcpy(p_msg->bd_addr, p_data->conn.p_bda);
|
||||
#if BLE_INCLUDED == TRUE
|
||||
@@ -3312,7 +3299,6 @@ void bta_dm_acl_change(tBTA_DM_MSG *p_data)
|
||||
APPL_TRACE_DEBUG("%s info: 0x%x", __func__, bta_dm_cb.device_list.peer_device[i].info);
|
||||
|
||||
if (bta_dm_cb.p_sec_cback) {
|
||||
conn.link_up.sc_downgrade = p_data->acl_change.sc_downgrade;
|
||||
bta_dm_cb.p_sec_cback(BTA_DM_LINK_UP_EVT, (tBTA_DM_SEC *)&conn);
|
||||
}
|
||||
} else {
|
||||
@@ -4347,7 +4333,8 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
|
||||
bdcpy(sec_event.ble_req.bd_addr, bda);
|
||||
p_name = BTM_SecReadDevName(bda);
|
||||
if (p_name != NULL) {
|
||||
BCM_STRNCPY_S((char *)sec_event.ble_req.bd_name, p_name, (BD_NAME_LEN));
|
||||
BCM_STRNCPY_S((char *)sec_event.ble_req.bd_name,
|
||||
sizeof(BD_NAME), p_name, (BD_NAME_LEN));
|
||||
} else {
|
||||
sec_event.ble_req.bd_name[0] = 0;
|
||||
}
|
||||
@@ -4359,7 +4346,8 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
|
||||
bdcpy(sec_event.key_notif.bd_addr, bda);
|
||||
p_name = BTM_SecReadDevName(bda);
|
||||
if (p_name != NULL) {
|
||||
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, p_name, (BD_NAME_LEN));
|
||||
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name,
|
||||
sizeof(BD_NAME), p_name, (BD_NAME_LEN));
|
||||
} else {
|
||||
sec_event.key_notif.bd_name[0] = 0;
|
||||
}
|
||||
@@ -4380,7 +4368,7 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
|
||||
|
||||
case BTM_LE_NC_REQ_EVT:
|
||||
bdcpy(sec_event.key_notif.bd_addr, bda);
|
||||
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, bta_dm_get_remname(), (BD_NAME_LEN));
|
||||
BCM_STRNCPY_S((char *)sec_event.key_notif.bd_name, sizeof(BD_NAME), bta_dm_get_remname(), (BD_NAME_LEN));
|
||||
sec_event.ble_req.bd_name[BD_NAME_LEN] = 0;
|
||||
sec_event.key_notif.passkey = p_data->key_notif;
|
||||
bta_dm_cb.p_sec_cback(BTA_DM_BLE_NC_REQ_EVT, &sec_event);
|
||||
@@ -4400,7 +4388,8 @@ static UINT8 bta_dm_ble_smp_cback (tBTM_LE_EVT event, BD_ADDR bda, tBTM_LE_EVT_D
|
||||
#endif
|
||||
p_name = BTM_SecReadDevName(bda);
|
||||
if (p_name != NULL) {
|
||||
BCM_STRNCPY_S((char *)sec_event.auth_cmpl.bd_name, p_name, (BD_NAME_LEN));
|
||||
BCM_STRNCPY_S((char *)sec_event.auth_cmpl.bd_name,
|
||||
sizeof(BD_NAME), p_name, (BD_NAME_LEN));
|
||||
} else {
|
||||
sec_event.auth_cmpl.bd_name[0] = 0;
|
||||
}
|
||||
@@ -4633,25 +4622,14 @@ void bta_dm_ble_set_scan_params(tBTA_DM_MSG *p_data)
|
||||
*******************************************************************************/
|
||||
void bta_dm_ble_set_scan_fil_params(tBTA_DM_MSG *p_data)
|
||||
{
|
||||
tBTA_STATUS status = BTA_FAILURE;
|
||||
|
||||
if (BTM_BleSetScanFilterParams (p_data->ble_set_scan_fil_params.client_if,
|
||||
BTM_BleSetScanFilterParams (p_data->ble_set_scan_fil_params.client_if,
|
||||
p_data->ble_set_scan_fil_params.scan_int,
|
||||
p_data->ble_set_scan_fil_params.scan_window,
|
||||
p_data->ble_set_scan_fil_params.scan_mode,
|
||||
p_data->ble_set_scan_fil_params.addr_type_own,
|
||||
p_data->ble_set_scan_fil_params.scan_duplicate_filter,
|
||||
p_data->ble_set_scan_fil_params.scan_filter_policy,
|
||||
p_data->ble_set_scan_fil_params.scan_param_setup_cback) == BTM_SUCCESS) {
|
||||
status = BTA_SUCCESS;
|
||||
|
||||
} else {
|
||||
APPL_TRACE_ERROR("%s(), fail to set scan params.", __func__);
|
||||
}
|
||||
if (p_data->ble_set_scan_fil_params.scan_param_setup_cback != NULL) {
|
||||
p_data->ble_set_scan_fil_params.scan_param_setup_cback(p_data->ble_set_scan_fil_params.client_if, status);
|
||||
}
|
||||
|
||||
p_data->ble_set_scan_fil_params.scan_param_setup_cback);
|
||||
}
|
||||
|
||||
|
||||
@@ -4894,8 +4872,7 @@ void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data)
|
||||
*******************************************************************************/
|
||||
void bta_dm_ble_set_adv_params_all (tBTA_DM_MSG *p_data)
|
||||
{
|
||||
tBTA_STATUS status = BTA_FAILURE;
|
||||
if (BTM_BleSetAdvParamsAll(p_data->ble_set_adv_params_all.adv_int_min,
|
||||
if (BTM_BleSetAdvParamsStartAdv(p_data->ble_set_adv_params_all.adv_int_min,
|
||||
p_data->ble_set_adv_params_all.adv_int_max,
|
||||
p_data->ble_set_adv_params_all.adv_type,
|
||||
p_data->ble_set_adv_params_all.addr_type_own,
|
||||
@@ -4903,19 +4880,9 @@ void bta_dm_ble_set_adv_params_all (tBTA_DM_MSG *p_data)
|
||||
p_data->ble_set_adv_params_all.channel_map,
|
||||
p_data->ble_set_adv_params_all.adv_filter_policy,
|
||||
p_data->ble_set_adv_params_all.p_start_adv_cback) == BTM_SUCCESS) {
|
||||
APPL_TRACE_DEBUG("%s(), success to set ble adv params.", __func__);
|
||||
APPL_TRACE_DEBUG("%s(), success to start ble adv.", __func__);
|
||||
} else {
|
||||
APPL_TRACE_ERROR("%s(), fail to set ble adv params.", __func__);
|
||||
if(p_data->ble_set_adv_params_all.p_start_adv_cback) {
|
||||
(*p_data->ble_set_adv_params_all.p_start_adv_cback)(status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(BTM_BleStartAdv() == BTM_SUCCESS) {
|
||||
status = BTA_SUCCESS;
|
||||
}
|
||||
if(p_data->ble_set_adv_params_all.p_start_adv_cback) {
|
||||
(*p_data->ble_set_adv_params_all.p_start_adv_cback)(status);
|
||||
APPL_TRACE_ERROR("%s(), fail to start ble adv.", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4958,29 +4925,6 @@ void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data)
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_ble_set_long_adv
|
||||
**
|
||||
** Description This function set the long ADV data
|
||||
**
|
||||
** Parameters:
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_dm_ble_set_long_adv (tBTA_DM_MSG *p_data)
|
||||
{
|
||||
tBTA_STATUS status = BTA_FAILURE;
|
||||
|
||||
if (BTM_BleWriteLongAdvData(p_data->ble_set_long_adv_data.adv_data,
|
||||
p_data->ble_set_long_adv_data.adv_data_len) == BTM_SUCCESS) {
|
||||
status = BTA_SUCCESS;
|
||||
}
|
||||
|
||||
if (p_data->ble_set_adv_data.p_adv_data_cback) {
|
||||
(*p_data->ble_set_adv_data.p_adv_data_cback)(status);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_ble_set_adv_config_raw
|
||||
@@ -5096,17 +5040,16 @@ void bta_dm_ble_set_data_length(tBTA_DM_MSG *p_data)
|
||||
*******************************************************************************/
|
||||
void bta_dm_ble_broadcast (tBTA_DM_MSG *p_data)
|
||||
{
|
||||
tBTA_STATUS status = BTA_FAILURE;
|
||||
tBTM_STATUS status = 0;
|
||||
BOOLEAN start = p_data->ble_observe.start;
|
||||
|
||||
if (BTM_BleBroadcast(start, p_data->ble_observe.p_stop_adv_cback) == BTM_SUCCESS) {
|
||||
status = BTA_SUCCESS;
|
||||
} else {
|
||||
APPL_TRACE_ERROR("%s failed\n", __FUNCTION__);
|
||||
}
|
||||
status = BTM_BleBroadcast(start, p_data->ble_observe.p_stop_adv_cback);
|
||||
|
||||
if (p_data->ble_observe.p_stop_adv_cback){
|
||||
(*p_data->ble_observe.p_stop_adv_cback)(status);
|
||||
if (status != BTM_SUCCESS){
|
||||
APPL_TRACE_WARNING("%s, %s, status=0x%x\n", __func__,\
|
||||
(start == TRUE) ? "start adv failed" : "stop adv failed", status);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5681,7 +5624,7 @@ static void bta_dm_gatt_disc_result(tBTA_GATT_ID service_id)
|
||||
|
||||
/* send result back to app now, one by one */
|
||||
bdcpy (result.disc_ble_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
|
||||
BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name,bta_dm_get_remname(), (BD_NAME_LEN - 1));
|
||||
BCM_STRNCPY_S((char *)result.disc_ble_res.bd_name, sizeof(BD_NAME), bta_dm_get_remname(), (BD_NAME_LEN - 1));
|
||||
result.disc_ble_res.bd_name[BD_NAME_LEN] = 0;
|
||||
memcpy(&result.disc_ble_res.service, &service_id.uuid, sizeof(tBT_UUID));
|
||||
|
||||
@@ -5723,7 +5666,8 @@ static void bta_dm_gatt_disc_complete(UINT16 conn_id, tBTA_GATT_STATUS status)
|
||||
p_msg->disc_result.result.disc_res.num_uuids = 0;
|
||||
p_msg->disc_result.result.disc_res.p_uuid_list = NULL;
|
||||
bdcpy (p_msg->disc_result.result.disc_res.bd_addr, bta_dm_search_cb.peer_bdaddr);
|
||||
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, bta_dm_get_remname(), (BD_NAME_LEN - 1));
|
||||
BCM_STRNCPY_S((char *)p_msg->disc_result.result.disc_res.bd_name, sizeof(BD_NAME),
|
||||
bta_dm_get_remname(), (BD_NAME_LEN - 1));
|
||||
|
||||
/* make sure the string is terminated */
|
||||
p_msg->disc_result.result.disc_res.bd_name[BD_NAME_LEN - 1] = 0;
|
||||
|
||||
@@ -174,7 +174,7 @@ void BTA_DmSetDeviceName(const char *p_name)
|
||||
if ((p_msg = (tBTA_DM_API_SET_NAME *) osi_malloc(sizeof(tBTA_DM_API_SET_NAME))) != NULL) {
|
||||
p_msg->hdr.event = BTA_DM_API_SET_NAME_EVT;
|
||||
/* truncate the name if needed */
|
||||
BCM_STRNCPY_S((char *)p_msg->name, p_name, BD_NAME_LEN - 1);
|
||||
BCM_STRNCPY_S((char *)p_msg->name, sizeof(p_msg->name), p_name, BD_NAME_LEN - 1);
|
||||
p_msg->name[BD_NAME_LEN - 1] = 0;
|
||||
|
||||
bta_sys_sendmsg(p_msg);
|
||||
@@ -510,36 +510,6 @@ void BTA_DmLocalOob(void)
|
||||
bta_sys_sendmsg(p_msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_DmOobReply
|
||||
**
|
||||
** This function is called to provide the OOB data for
|
||||
** SMP in response to BTM_LE_OOB_REQ_EVT
|
||||
**
|
||||
** Parameters: bd_addr - Address of the peer device
|
||||
** len - length of simple pairing Randomizer C
|
||||
** p_value - simple pairing Randomizer C.
|
||||
**
|
||||
** Returns void
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_DmOobReply(BD_ADDR bd_addr, UINT8 len, UINT8 *p_value)
|
||||
{
|
||||
tBTA_DM_API_OOB_REPLY *p_msg;
|
||||
|
||||
if ((p_msg = (tBTA_DM_API_OOB_REPLY *) osi_malloc(sizeof(tBTA_DM_API_OOB_REPLY))) != NULL) {
|
||||
p_msg->hdr.event = BTA_DM_API_OOB_REPLY_EVT;
|
||||
if(p_value == NULL || len > BT_OCTET16_LEN) {
|
||||
return;
|
||||
}
|
||||
memcpy(p_msg->bd_addr, bd_addr, BD_ADDR_LEN);
|
||||
p_msg->len = len;
|
||||
memcpy(p_msg->value, p_value, len);
|
||||
bta_sys_sendmsg(p_msg);
|
||||
}
|
||||
}
|
||||
#endif /* BTM_OOB_INCLUDED */
|
||||
/*******************************************************************************
|
||||
**
|
||||
@@ -586,7 +556,6 @@ void BTA_DmPasskeyReqReply(BOOLEAN accept, BD_ADDR bd_addr, UINT32 passkey)
|
||||
}
|
||||
}
|
||||
#endif ///BT_SSP_INCLUDED == TRUE
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_DmAddDevice
|
||||
@@ -600,8 +569,7 @@ void BTA_DmPasskeyReqReply(BOOLEAN accept, BD_ADDR bd_addr, UINT32 passkey)
|
||||
*******************************************************************************/
|
||||
void BTA_DmAddDevice(BD_ADDR bd_addr, DEV_CLASS dev_class, LINK_KEY link_key,
|
||||
tBTA_SERVICE_MASK trusted_mask, BOOLEAN is_trusted,
|
||||
UINT8 key_type, tBTA_IO_CAP io_cap, UINT8 pin_length,
|
||||
UINT8 sc_support)
|
||||
UINT8 key_type, tBTA_IO_CAP io_cap, UINT8 pin_length)
|
||||
{
|
||||
|
||||
tBTA_DM_API_ADD_DEVICE *p_msg;
|
||||
@@ -614,7 +582,6 @@ void BTA_DmAddDevice(BD_ADDR bd_addr, DEV_CLASS dev_class, LINK_KEY link_key,
|
||||
p_msg->tm = trusted_mask;
|
||||
p_msg->is_trusted = is_trusted;
|
||||
p_msg->io_cap = io_cap;
|
||||
p_msg->sc_support = sc_support;
|
||||
|
||||
if (link_key) {
|
||||
p_msg->link_key_known = TRUE;
|
||||
@@ -665,6 +632,7 @@ tBTA_STATUS BTA_DmRemoveDevice(BD_ADDR bd_addr, tBT_TRANSPORT transport)
|
||||
|
||||
return BTA_SUCCESS;
|
||||
}
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
@@ -738,7 +706,7 @@ UINT16 BTA_DmGetConnectionState( BD_ADDR bd_addr )
|
||||
**
|
||||
** Description This function adds a DI record to the local SDP database.
|
||||
**
|
||||
** Returns BTA_SUCCESS if record set successfully, otherwise error code.
|
||||
** Returns BTA_SUCCESS if record set sucessfully, otherwise error code.
|
||||
**
|
||||
*******************************************************************************/
|
||||
tBTA_STATUS BTA_DmSetLocalDiRecord( tBTA_DI_RECORD *p_device_info,
|
||||
@@ -1224,46 +1192,16 @@ void BTA_DmBleSetAdvConfigRaw (UINT8 *p_raw_adv, UINT32 raw_adv_len,
|
||||
tBTA_DM_API_SET_ADV_CONFIG_RAW *p_msg;
|
||||
|
||||
if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG_RAW *)
|
||||
osi_malloc(sizeof(tBTA_DM_API_SET_ADV_CONFIG_RAW) + raw_adv_len)) != NULL) {
|
||||
osi_malloc(sizeof(tBTA_DM_API_SET_ADV_CONFIG_RAW))) != NULL) {
|
||||
p_msg->hdr.event = BTA_DM_API_BLE_SET_ADV_CONFIG_RAW_EVT;
|
||||
p_msg->p_adv_data_cback = p_adv_data_cback;
|
||||
p_msg->p_raw_adv = (UINT8 *)(p_msg + 1);
|
||||
memcpy(p_msg->p_raw_adv, p_raw_adv, raw_adv_len);
|
||||
p_msg->p_raw_adv = p_raw_adv;
|
||||
p_msg->raw_adv_len = raw_adv_len;
|
||||
|
||||
bta_sys_sendmsg(p_msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_DmBleSetLongAdv
|
||||
**
|
||||
** Description This function is called to set long Advertising data
|
||||
**
|
||||
** Parameters adv_data : long advertising data.
|
||||
** adv_data_len : long advertising data length.
|
||||
** p_adv_data_cback : set long adv data complete callback.
|
||||
**
|
||||
** Returns None
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_DmBleSetLongAdv (UINT8 *adv_data, UINT32 adv_data_len,
|
||||
tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback)
|
||||
{
|
||||
tBTA_DM_API_SET_LONG_ADV *p_msg;
|
||||
|
||||
if ((p_msg = (tBTA_DM_API_SET_LONG_ADV *)
|
||||
osi_malloc(sizeof(tBTA_DM_API_SET_LONG_ADV))) != NULL) {
|
||||
p_msg->hdr.event = BTA_DM_API_BLE_SET_LONG_ADV_EVT;
|
||||
p_msg->p_adv_data_cback = p_adv_data_cback;
|
||||
p_msg->adv_data = adv_data;
|
||||
p_msg->adv_data_len = adv_data_len;
|
||||
|
||||
bta_sys_sendmsg(p_msg);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_DmBleSetScanRsp
|
||||
@@ -1310,11 +1248,10 @@ void BTA_DmBleSetScanRspRaw (UINT8 *p_raw_scan_rsp, UINT32 raw_scan_rsp_len,
|
||||
tBTA_DM_API_SET_ADV_CONFIG_RAW *p_msg;
|
||||
|
||||
if ((p_msg = (tBTA_DM_API_SET_ADV_CONFIG_RAW *)
|
||||
osi_malloc(sizeof(tBTA_DM_API_SET_ADV_CONFIG_RAW) + raw_scan_rsp_len)) != NULL) {
|
||||
osi_malloc(sizeof(tBTA_DM_API_SET_ADV_CONFIG_RAW))) != NULL) {
|
||||
p_msg->hdr.event = BTA_DM_API_BLE_SET_SCAN_RSP_RAW_EVT;
|
||||
p_msg->p_adv_data_cback = p_scan_rsp_data_cback;
|
||||
p_msg->p_raw_adv = (UINT8 *)(p_msg + 1);
|
||||
memcpy(p_msg->p_raw_adv, p_raw_scan_rsp, raw_scan_rsp_len);
|
||||
p_msg->p_raw_adv = p_raw_scan_rsp;
|
||||
p_msg->raw_adv_len = raw_scan_rsp_len;
|
||||
|
||||
bta_sys_sendmsg(p_msg);
|
||||
@@ -1821,7 +1758,7 @@ void BTA_DmBleConfigLocalIcon(uint16_t icon)
|
||||
** p_cback: callback function associated to this adv instance.
|
||||
** p_ref: reference data pointer to this adv instance.
|
||||
**
|
||||
** Returns BTA_SUCCESS if command started successfully; otherwise failure.
|
||||
** Returns BTA_SUCCESS if command started sucessfully; otherwise failure.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_BleEnableAdvInstance (tBTA_BLE_ADV_PARAMS *p_params,
|
||||
@@ -1859,7 +1796,7 @@ void BTA_BleEnableAdvInstance (tBTA_BLE_ADV_PARAMS *p_params,
|
||||
** Parameters inst_id: Adv instance to update the parameter.
|
||||
** p_params: pointer to the adv parameter structure.
|
||||
**
|
||||
** Returns BTA_SUCCESS if command started successfully; otherwise failure.
|
||||
** Returns BTA_SUCCESS if command started sucessfully; otherwise failure.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_BleUpdateAdvInstParam (UINT8 inst_id, tBTA_BLE_ADV_PARAMS *p_params)
|
||||
@@ -1894,7 +1831,7 @@ void BTA_BleUpdateAdvInstParam (UINT8 inst_id, tBTA_BLE_ADV_PARAMS *p_params)
|
||||
** memory space can not be freed until BTA_BLE_MULTI_ADV_DATA_EVT
|
||||
** is sent to application.
|
||||
**
|
||||
** Returns BTA_SUCCESS if command started successfully; otherwise failure.
|
||||
** Returns BTA_SUCCESS if command started sucessfully; otherwise failure.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp,
|
||||
@@ -1927,7 +1864,7 @@ void BTA_BleCfgAdvInstData (UINT8 inst_id, BOOLEAN is_scan_rsp,
|
||||
**
|
||||
** Parameter inst_id: instance ID to disable.
|
||||
**
|
||||
** Returns BTA_SUCCESS if command started successfully; otherwise failure.
|
||||
** Returns BTA_SUCCESS if command started sucessfully; otherwise failure.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_BleDisableAdvInstance (UINT8 inst_id) //this function just used for vendor debug
|
||||
|
||||
@@ -228,9 +228,9 @@ tBTA_DM_PM_TYPE_QUALIFIER tBTA_DM_PM_SPEC bta_dm_pm_spec[BTA_DM_NUM_PM_SPEC] = {
|
||||
{{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_SNIFF3, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco open, active */
|
||||
{{BTA_DM_PM_SNIFF, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* sco close sniff */
|
||||
{{BTA_DM_PM_SNIFF, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}}, /* idle */
|
||||
{{BTA_DM_PM_ACTIVE, 0}, {BTA_DM_PM_NO_ACTION, 0}}, /* busy */
|
||||
{{BTA_DM_PM_RETRY, 7000 + BTA_DM_PM_SPEC_TO_OFFSET}, {BTA_DM_PM_NO_ACTION, 0}} /* mode change retry */
|
||||
}
|
||||
|
||||
@@ -35,9 +35,6 @@
|
||||
#define BTM_BLE_ONLY_ACCEPT_SPECIFIED_SEC_AUTH_DISABLE 0
|
||||
#define BTM_BLE_ONLY_ACCEPT_SPECIFIED_SEC_AUTH_ENABLE 1
|
||||
|
||||
#define BTM_BLE_OOB_DISABLE 0
|
||||
#define BTM_BLE_OOB_ENABLE 1
|
||||
|
||||
tBTE_APPL_CFG bte_appl_cfg = {
|
||||
#if SMP_INCLUDED == TRUE
|
||||
BTA_LE_AUTH_REQ_SC_MITM_BOND, // Authentication requirements
|
||||
@@ -48,9 +45,7 @@ tBTE_APPL_CFG bte_appl_cfg = {
|
||||
BTM_BLE_INITIATOR_KEY_SIZE,
|
||||
BTM_BLE_RESPONDER_KEY_SIZE,
|
||||
BTM_BLE_MAX_KEY_SIZE,
|
||||
BTM_BLE_MIN_KEY_SIZE,
|
||||
BTM_BLE_ONLY_ACCEPT_SPECIFIED_SEC_AUTH_DISABLE,
|
||||
BTM_BLE_OOB_DISABLE,
|
||||
BTM_BLE_ONLY_ACCEPT_SPECIFIED_SEC_AUTH_DISABLE
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -343,16 +338,12 @@ void bta_dm_co_ble_io_req(BD_ADDR bd_addr, tBTA_IO_CAP *p_io_cap,
|
||||
* If the answer can not be obtained right away,
|
||||
* set *p_oob_data to BTA_OOB_UNKNOWN and call bta_dm_ci_io_req() when the answer is available */
|
||||
|
||||
*p_oob_data = bte_appl_cfg.oob_support;
|
||||
*p_oob_data = FALSE;
|
||||
|
||||
/* *p_auth_req by default is FALSE for devices with NoInputNoOutput; TRUE for other devices. */
|
||||
|
||||
*p_auth_req = bte_appl_cfg.ble_auth_req | (bte_appl_cfg.ble_auth_req & BTA_LE_AUTH_REQ_MITM) | ((*p_auth_req) & BTA_LE_AUTH_REQ_MITM);
|
||||
|
||||
if (*p_oob_data == BTM_BLE_OOB_ENABLE) {
|
||||
*p_auth_req = (*p_auth_req)&(~BTA_LE_AUTH_REQ_SC_ONLY);
|
||||
}
|
||||
|
||||
if (bte_appl_cfg.ble_io_cap <= 4) {
|
||||
*p_io_cap = bte_appl_cfg.ble_io_cap;
|
||||
}
|
||||
@@ -408,7 +399,7 @@ void bta_dm_co_ble_set_rsp_key_req(UINT8 rsp_key)
|
||||
void bta_dm_co_ble_set_max_key_size(UINT8 ble_key_size)
|
||||
{
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
if(ble_key_size >= bte_appl_cfg.ble_min_key_size && ble_key_size <= BTM_BLE_MAX_KEY_SIZE) {
|
||||
if(ble_key_size >= BTM_BLE_MIN_KEY_SIZE && ble_key_size <= BTM_BLE_MAX_KEY_SIZE) {
|
||||
bte_appl_cfg.ble_max_key_size = ble_key_size;
|
||||
} else {
|
||||
APPL_TRACE_ERROR("%s error:Invalid key size value, key_size =%d",__func__, ble_key_size);
|
||||
@@ -416,17 +407,6 @@ void bta_dm_co_ble_set_max_key_size(UINT8 ble_key_size)
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
}
|
||||
|
||||
void bta_dm_co_ble_set_min_key_size(UINT8 ble_key_size)
|
||||
{
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
if(ble_key_size >= BTM_BLE_MIN_KEY_SIZE && ble_key_size <= bte_appl_cfg.ble_max_key_size) {
|
||||
bte_appl_cfg.ble_min_key_size = ble_key_size;
|
||||
} else {
|
||||
APPL_TRACE_ERROR("%s error:Invalid key size value, key_size =%d",__func__, ble_key_size);
|
||||
}
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
}
|
||||
|
||||
void bta_dm_co_ble_set_accept_auth_enable(UINT8 enable)
|
||||
{
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
@@ -453,16 +433,5 @@ UINT8 bta_dm_co_ble_get_auth_req(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bta_dm_co_ble_oob_support(UINT8 enable)
|
||||
{
|
||||
#if (SMP_INCLUDED == TRUE)
|
||||
if (enable) {
|
||||
bte_appl_cfg.oob_support = BTM_BLE_OOB_ENABLE;
|
||||
} else {
|
||||
bte_appl_cfg.oob_support = BTM_BLE_OOB_DISABLE;
|
||||
}
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
#include "osi/allocator.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "esp_coexist.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants and types
|
||||
@@ -83,7 +82,6 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
#if (BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
|
||||
bta_dm_loc_oob, /* BTA_DM_API_LOC_OOB_EVT */
|
||||
bta_dm_oob_reply, /* BTA_DM_API_OOB_REPLY_EVT */
|
||||
bta_dm_ci_io_req_act, /* BTA_DM_CI_IO_REQ_EVT */
|
||||
bta_dm_ci_rmt_oob_act, /* BTA_DM_CI_RMT_OOB_EVT */
|
||||
#endif /* BTM_OOB_INCLUDED */
|
||||
@@ -132,7 +130,6 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
|
||||
bta_dm_ble_set_scan_rsp_raw, /* BTA_DM_API_BLE_SET_SCAN_RSP_RAW_EVT */
|
||||
bta_dm_ble_broadcast, /* BTA_DM_API_BLE_BROADCAST_EVT */
|
||||
bta_dm_ble_set_data_length, /* BTA_DM_API_SET_DATA_LENGTH_EVT */
|
||||
bta_dm_ble_set_long_adv, /* BTA_DM_API_BLE_SET_LONG_ADV_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 */
|
||||
@@ -453,27 +450,3 @@ BOOLEAN bta_dm_search_sm_execute(BT_HDR *p_msg)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void BTA_DmCoexEventTrigger(uint32_t event)
|
||||
{
|
||||
switch(event) {
|
||||
case BTA_COEX_EVT_SCAN_STARTED:
|
||||
case BTA_COEX_EVT_SCAN_STOPPED:
|
||||
case BTA_COEX_EVT_SNIFF_ENTER:
|
||||
case BTA_COEX_EVT_SNIFF_EXIT:
|
||||
case BTA_COEX_EVT_A2DP_PAUSED_ENTER:
|
||||
case BTA_COEX_EVT_A2DP_PAUSED_EXIT:
|
||||
case BTA_COEX_EVT_ACL_CONNECTED:
|
||||
case BTA_COEX_EVT_ACL_DISCONNECTED:
|
||||
break;
|
||||
case BTA_COEX_EVT_STREAMING_STARTED:
|
||||
esp_coex_status_bit_set(ESP_COEX_ST_TYPE_BT, ESP_COEX_BT_ST_A2DP_STREAMING);
|
||||
esp_coex_status_bit_clear(ESP_COEX_ST_TYPE_BT, ESP_COEX_BT_ST_A2DP_PAUSED);
|
||||
break;
|
||||
case BTA_COEX_EVT_STREAMING_STOPPED:
|
||||
esp_coex_status_bit_clear(ESP_COEX_ST_TYPE_BT, ESP_COEX_BT_ST_A2DP_STREAMING);
|
||||
esp_coex_status_bit_clear(ESP_COEX_ST_TYPE_BT, ESP_COEX_BT_ST_A2DP_PAUSED);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@
|
||||
#define BTA_DM_INT_H
|
||||
|
||||
#include "common/bt_target.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#if (BLE_INCLUDED == TRUE && (defined BTA_GATT_INCLUDED) && (BTA_GATT_INCLUDED == TRUE))
|
||||
#include "bta/bta_gatt_api.h"
|
||||
#endif
|
||||
@@ -79,7 +79,6 @@ enum {
|
||||
#endif ///SMP_INCLUDED == TRUE
|
||||
#if (BTM_OOB_INCLUDED == TRUE && SMP_INCLUDED == TRUE)
|
||||
BTA_DM_API_LOC_OOB_EVT,
|
||||
BTA_DM_API_OOB_REPLY_EVT,
|
||||
BTA_DM_CI_IO_REQ_EVT,
|
||||
BTA_DM_CI_RMT_OOB_EVT,
|
||||
#endif /* BTM_OOB_INCLUDED */
|
||||
@@ -128,7 +127,7 @@ enum {
|
||||
BTA_DM_API_BLE_SET_SCAN_RSP_RAW_EVT,
|
||||
BTA_DM_API_BLE_BROADCAST_EVT,
|
||||
BTA_DM_API_SET_DATA_LENGTH_EVT,
|
||||
BTA_DM_API_BLE_SET_LONG_ADV_EVT,
|
||||
|
||||
#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
|
||||
BTA_DM_API_CFG_FILTER_COND_EVT,
|
||||
BTA_DM_API_SCAN_FILTER_SETUP_EVT,
|
||||
@@ -308,14 +307,6 @@ typedef struct {
|
||||
BT_HDR hdr;
|
||||
} tBTA_DM_API_LOC_OOB;
|
||||
|
||||
/* data type for BTA_DM_API_OOB_REPLY_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
BD_ADDR bd_addr;
|
||||
UINT8 len;
|
||||
UINT8 value[BT_OCTET16_LEN];
|
||||
} tBTA_DM_API_OOB_REPLY;
|
||||
|
||||
/* data type for BTA_DM_API_CONFIRM_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
@@ -384,7 +375,6 @@ typedef struct {
|
||||
UINT8 new_role;
|
||||
BD_ADDR bd_addr;
|
||||
UINT8 hci_status;
|
||||
BOOLEAN sc_downgrade;
|
||||
#if BLE_INCLUDED == TRUE
|
||||
UINT16 handle;
|
||||
tBT_TRANSPORT transport;
|
||||
@@ -426,7 +416,6 @@ typedef struct {
|
||||
BD_NAME bd_name;
|
||||
UINT8 features[BTA_FEATURE_BYTES_PER_PAGE * (BTA_EXT_FEATURES_PAGE_MAX + 1)];
|
||||
UINT8 pin_length;
|
||||
UINT8 sc_support;
|
||||
} tBTA_DM_API_ADD_DEVICE;
|
||||
|
||||
/* data type for BTA_DM_API_REMOVE_ACL_EVT */
|
||||
@@ -668,13 +657,6 @@ typedef struct {
|
||||
tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback;
|
||||
} tBTA_DM_API_SET_ADV_CONFIG_RAW;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT8 *adv_data;
|
||||
UINT8 adv_data_len;
|
||||
tBTA_SET_ADV_DATA_CMPL_CBACK *p_adv_data_cback;
|
||||
} tBTA_DM_API_SET_LONG_ADV;
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT8 batch_scan_full_max;
|
||||
@@ -807,7 +789,6 @@ typedef union {
|
||||
tBTA_DM_API_PIN_REPLY pin_reply;
|
||||
|
||||
tBTA_DM_API_LOC_OOB loc_oob;
|
||||
tBTA_DM_API_OOB_REPLY oob_reply;
|
||||
tBTA_DM_API_CONFIRM confirm;
|
||||
tBTA_DM_API_KEY_REQ key_req;
|
||||
tBTA_DM_CI_IO_REQ ci_io_req;
|
||||
@@ -855,7 +836,6 @@ typedef union {
|
||||
tBTA_DM_API_BLE_ADV_PARAMS_ALL ble_set_adv_params_all;
|
||||
tBTA_DM_API_SET_ADV_CONFIG ble_set_adv_data;
|
||||
tBTA_DM_API_SET_ADV_CONFIG_RAW ble_set_adv_data_raw;
|
||||
tBTA_DM_API_SET_LONG_ADV ble_set_long_adv_data;
|
||||
#if BLE_ANDROID_CONTROLLER_SCAN_FILTER == TRUE
|
||||
tBTA_DM_API_SCAN_FILTER_PARAM_SETUP ble_scan_filt_param_setup;
|
||||
tBTA_DM_API_CFG_FILTER_COND ble_cfg_filter_cond;
|
||||
@@ -1211,7 +1191,6 @@ extern tBTA_DM_DI_CB bta_dm_di_cb;
|
||||
#else
|
||||
extern tBTA_DM_DI_CB *bta_dm_di_cb_ptr;
|
||||
#define bta_dm_di_cb (*bta_dm_di_cb_ptr)
|
||||
SemaphoreHandle_t deinit_semaphore;
|
||||
#endif
|
||||
|
||||
extern BOOLEAN bta_dm_sm_execute(BT_HDR *p_msg);
|
||||
@@ -1269,7 +1248,6 @@ extern void bta_dm_ble_config_local_icon (tBTA_DM_MSG *p_data);
|
||||
extern void bta_dm_ble_set_adv_params (tBTA_DM_MSG *p_data);
|
||||
extern void bta_dm_ble_set_adv_params_all(tBTA_DM_MSG *p_data);
|
||||
extern void bta_dm_ble_set_adv_config (tBTA_DM_MSG *p_data);
|
||||
extern void bta_dm_ble_set_long_adv (tBTA_DM_MSG *p_data);
|
||||
extern void bta_dm_ble_set_adv_config_raw (tBTA_DM_MSG *p_data);
|
||||
extern void bta_dm_ble_set_scan_rsp (tBTA_DM_MSG *p_data);
|
||||
extern void bta_dm_ble_set_scan_rsp_raw (tBTA_DM_MSG *p_data);
|
||||
@@ -1299,7 +1277,6 @@ extern void bta_dm_confirm(tBTA_DM_MSG *p_data);
|
||||
extern void bta_dm_key_req(tBTA_DM_MSG *p_data);
|
||||
#if (BTM_OOB_INCLUDED == TRUE)
|
||||
extern void bta_dm_loc_oob(tBTA_DM_MSG *p_data);
|
||||
extern void bta_dm_oob_reply(tBTA_DM_MSG *p_data);
|
||||
extern void bta_dm_ci_io_req_act(tBTA_DM_MSG *p_data);
|
||||
extern void bta_dm_ci_rmt_oob_act(tBTA_DM_MSG *p_data);
|
||||
#endif /* BTM_OOB_INCLUDED */
|
||||
|
||||
@@ -27,10 +27,4 @@
|
||||
void BTA_GATT_SetLocalMTU(uint16_t mtu)
|
||||
{
|
||||
gatt_set_local_mtu(mtu);
|
||||
}
|
||||
|
||||
uint16_t BTA_GATT_GetLocalMTU(void)
|
||||
{
|
||||
return gatt_get_local_mtu();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -745,8 +745,6 @@ void bta_gattc_conncback(tBTA_GATTC_RCB *p_rcb, tBTA_GATTC_DATA *p_data)
|
||||
void bta_gattc_disconncback(tBTA_GATTC_RCB *p_rcb, tBTA_GATTC_DATA *p_data)
|
||||
{
|
||||
if (p_rcb) {
|
||||
// Clear up the notification registration information by BD_ADDR
|
||||
bta_gattc_clear_notif_registration_by_bda(p_rcb, p_data->int_conn.remote_bda);
|
||||
bta_gattc_send_disconnect_cback(p_rcb,
|
||||
p_data->int_conn.reason,
|
||||
p_data->int_conn.remote_bda,
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include "bta/bta_sys.h"
|
||||
#include "bta/bta_gatt_api.h"
|
||||
#include "bta_gattc_int.h"
|
||||
#include "stack/l2c_api.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
@@ -76,7 +76,7 @@ void BTA_GATTC_Disable(void)
|
||||
** Description This function is called to register application callbacks
|
||||
** with BTA GATTC module.
|
||||
**
|
||||
** Parameters p_app_uuid - application UUID
|
||||
** Parameters p_app_uuid - applicaiton UUID
|
||||
** p_client_cb - pointer to the application callback function.
|
||||
**
|
||||
** Returns None
|
||||
@@ -178,11 +178,6 @@ void BTA_GATTC_Open(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, tBTA_ADDR_TYPE
|
||||
*******************************************************************************/
|
||||
void BTA_GATTC_CancelOpen(tBTA_GATTC_IF client_if, BD_ADDR remote_bda, BOOLEAN is_direct)
|
||||
{
|
||||
//If the registration callback is NULL, return
|
||||
if(bta_sys_is_register(BTA_ID_GATTC) == FALSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
tBTA_GATTC_API_CANCEL_OPEN *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_GATTC_API_CANCEL_OPEN *) osi_malloc(sizeof(tBTA_GATTC_API_CANCEL_OPEN))) != NULL) {
|
||||
@@ -338,13 +333,13 @@ const tBTA_GATTC_DESCRIPTOR* BTA_GATTC_GetDescriptor(UINT16 conn_id, UINT16 hand
|
||||
}
|
||||
|
||||
void BTA_GATTC_GetServiceWithUUID(UINT16 conn_id, tBT_UUID *svc_uuid,
|
||||
btgatt_db_element_t **db, UINT16 *count)
|
||||
btgatt_db_element_t **db, int *count)
|
||||
{
|
||||
bta_gattc_get_service_with_uuid(conn_id, svc_uuid, db, count);
|
||||
}
|
||||
|
||||
void BTA_GATTC_GetAllChar(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle,
|
||||
btgatt_db_element_t **db, UINT16 *count)
|
||||
btgatt_db_element_t **db, int *count)
|
||||
{
|
||||
bta_gattc_get_db_with_opration(conn_id,
|
||||
GATT_OP_GET_ALL_CHAR,
|
||||
@@ -359,7 +354,7 @@ void BTA_GATTC_GetAllChar(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle
|
||||
}
|
||||
|
||||
void BTA_GATTC_GetAllDescriptor(UINT16 conn_id, UINT16 char_handle,
|
||||
btgatt_db_element_t **db, UINT16 *count)
|
||||
btgatt_db_element_t **db, int *count)
|
||||
{
|
||||
bta_gattc_get_db_with_opration(conn_id,
|
||||
GATT_OP_GET_ALL_DESCRI,
|
||||
@@ -374,7 +369,7 @@ void BTA_GATTC_GetAllDescriptor(UINT16 conn_id, UINT16 char_handle,
|
||||
}
|
||||
|
||||
void BTA_GATTC_GetCharByUUID(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, tBT_UUID char_uuid,
|
||||
btgatt_db_element_t **db, UINT16 *count)
|
||||
btgatt_db_element_t **db, int *count)
|
||||
{
|
||||
bta_gattc_get_db_with_opration(conn_id,
|
||||
GATT_OP_GET_CHAR_BY_UUID,
|
||||
@@ -390,7 +385,7 @@ void BTA_GATTC_GetCharByUUID(UINT16 conn_id, UINT16 start_handle, UINT16 end_han
|
||||
|
||||
void BTA_GATTC_GetDescrByUUID(UINT16 conn_id, uint16_t start_handle, uint16_t end_handle,
|
||||
tBT_UUID char_uuid, tBT_UUID descr_uuid,
|
||||
btgatt_db_element_t **db, UINT16 *count)
|
||||
btgatt_db_element_t **db, int *count)
|
||||
{
|
||||
bta_gattc_get_db_with_opration(conn_id,
|
||||
GATT_OP_GET_DESCRI_BY_UUID,
|
||||
@@ -405,7 +400,7 @@ void BTA_GATTC_GetDescrByUUID(UINT16 conn_id, uint16_t start_handle, uint16_t en
|
||||
}
|
||||
|
||||
void BTA_GATTC_GetDescrByCharHandle(UINT16 conn_id, UINT16 char_handle, tBT_UUID descr_uuid,
|
||||
btgatt_db_element_t **db, UINT16 *count)
|
||||
btgatt_db_element_t **db, int *count)
|
||||
{
|
||||
bta_gattc_get_db_with_opration(conn_id,
|
||||
GATT_OP_GET_DESCRI_BY_HANDLE,
|
||||
@@ -420,7 +415,7 @@ void BTA_GATTC_GetDescrByCharHandle(UINT16 conn_id, UINT16 char_handle, tBT_UUID
|
||||
}
|
||||
|
||||
void BTA_GATTC_GetIncludeService(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle,
|
||||
tBT_UUID *incl_uuid, btgatt_db_element_t **db, UINT16 *count)
|
||||
tBT_UUID *incl_uuid, btgatt_db_element_t **db, int *count)
|
||||
{
|
||||
bta_gattc_get_db_with_opration(conn_id,
|
||||
GATT_OP_GET_INCLUDE_SVC,
|
||||
@@ -434,13 +429,13 @@ void BTA_GATTC_GetIncludeService(UINT16 conn_id, UINT16 start_handle, UINT16 end
|
||||
count);
|
||||
}
|
||||
|
||||
void BTA_GATTC_GetDBSize(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, UINT16 *count)
|
||||
void BTA_GATTC_GetDBSize(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, int *count)
|
||||
{
|
||||
bta_gattc_get_db_size_handle(conn_id, start_handle, end_handle, count);
|
||||
}
|
||||
|
||||
void BTA_GATTC_GetDBSizeByType(UINT16 conn_id, bt_gatt_db_attribute_type_t type,
|
||||
UINT16 start_handle, UINT16 end_handle, UINT16 char_handle, UINT16 *count)
|
||||
UINT16 start_handle, UINT16 end_handle, UINT16 char_handle, int *count)
|
||||
{
|
||||
bta_gattc_get_db_size_with_type_handle(conn_id, type, start_handle, end_handle, char_handle, count);
|
||||
}
|
||||
@@ -459,7 +454,7 @@ void BTA_GATTC_GetDBSizeByType(UINT16 conn_id, bt_gatt_db_attribute_type_t type,
|
||||
**
|
||||
*******************************************************************************/
|
||||
void BTA_GATTC_GetGattDb(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle,
|
||||
btgatt_db_element_t **db, UINT16 *count)
|
||||
btgatt_db_element_t **db, int *count)
|
||||
{
|
||||
bta_gattc_get_gatt_db(conn_id, start_handle, end_handle, db, count);
|
||||
}
|
||||
@@ -603,10 +598,6 @@ void BTA_GATTC_WriteCharValue ( UINT16 conn_id,
|
||||
memcpy(p_buf->p_value, p_value, len);
|
||||
}
|
||||
|
||||
if(write_type == BTA_GATTC_TYPE_WRITE_NO_RSP){
|
||||
l2ble_update_att_acl_pkt_num(L2CA_DECREASE_BTC_NUM, NULL);
|
||||
l2ble_update_att_acl_pkt_num(L2CA_ADD_BTU_NUM, NULL);
|
||||
}
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
@@ -654,10 +645,6 @@ void BTA_GATTC_WriteCharDescr (UINT16 conn_id,
|
||||
memcpy(p_buf->p_value, p_data->p_value, p_data->len);
|
||||
}
|
||||
|
||||
if(write_type == BTA_GATTC_TYPE_WRITE_NO_RSP){
|
||||
l2ble_update_att_acl_pkt_num(L2CA_DECREASE_BTC_NUM, NULL);
|
||||
l2ble_update_att_acl_pkt_num(L2CA_ADD_BTU_NUM, NULL);
|
||||
}
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
@@ -938,10 +925,7 @@ void BTA_GATTC_Refresh(BD_ADDR remote_bda, bool erase_flash)
|
||||
bta_gattc_cache_reset(remote_bda);
|
||||
}
|
||||
#endif
|
||||
//If the registration callback is NULL, return
|
||||
if(bta_sys_is_register(BTA_ID_GATTC) == FALSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
tBTA_GATTC_API_OPEN *p_buf;
|
||||
|
||||
if ((p_buf = (tBTA_GATTC_API_OPEN *) osi_malloc(sizeof(tBTA_GATTC_API_OPEN))) != NULL) {
|
||||
|
||||
@@ -1227,7 +1227,7 @@ tBTA_GATTC_DESCRIPTOR* bta_gattc_get_descriptor(UINT16 conn_id, UINT16 handle)
|
||||
|
||||
void bta_gattc_get_service_with_uuid(UINT16 conn_id, tBT_UUID *svc_uuid,
|
||||
btgatt_db_element_t **svc_db,
|
||||
UINT16 *count)
|
||||
int *count)
|
||||
{
|
||||
const list_t* svc = bta_gattc_get_services(conn_id);
|
||||
if(!svc) {
|
||||
@@ -1301,7 +1301,7 @@ void bta_gattc_get_db_with_opration(UINT16 conn_id,
|
||||
tBT_UUID *descr_uuid,
|
||||
UINT16 start_handle, UINT16 end_handle,
|
||||
btgatt_db_element_t **char_db,
|
||||
UINT16 *count)
|
||||
int *count)
|
||||
{
|
||||
tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
|
||||
|
||||
@@ -1666,7 +1666,7 @@ static size_t bta_gattc_get_db_size(list_t *services,
|
||||
return db_size;
|
||||
}
|
||||
|
||||
void bta_gattc_get_db_size_handle(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, UINT16 *count)
|
||||
void bta_gattc_get_db_size_handle(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, int *count)
|
||||
{
|
||||
tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
|
||||
|
||||
@@ -1685,7 +1685,7 @@ void bta_gattc_get_db_size_handle(UINT16 conn_id, UINT16 start_handle, UINT16 en
|
||||
}
|
||||
|
||||
void bta_gattc_get_db_size_with_type_handle(UINT16 conn_id, bt_gatt_db_attribute_type_t type,
|
||||
UINT16 start_handle, UINT16 end_handle, UINT16 char_handle, UINT16 *count)
|
||||
UINT16 start_handle, UINT16 end_handle, UINT16 char_handle, int *count)
|
||||
{
|
||||
tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
|
||||
|
||||
@@ -1732,7 +1732,7 @@ void bta_gattc_get_db_size_with_type_handle(UINT16 conn_id, bt_gatt_db_attribute
|
||||
static void bta_gattc_get_gatt_db_impl(tBTA_GATTC_SERV *p_srvc_cb,
|
||||
UINT16 start_handle, UINT16 end_handle,
|
||||
btgatt_db_element_t **db,
|
||||
UINT16 *count)
|
||||
int *count)
|
||||
{
|
||||
APPL_TRACE_DEBUG("%s: start_handle 0x%04x, end_handle 0x%04x",
|
||||
__func__, start_handle, end_handle);
|
||||
@@ -1880,7 +1880,7 @@ static void bta_gattc_get_gatt_db_impl(tBTA_GATTC_SERV *p_srvc_cb,
|
||||
** Returns None.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gattc_get_gatt_db(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, btgatt_db_element_t **db, UINT16 *count)
|
||||
void bta_gattc_get_gatt_db(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, btgatt_db_element_t **db, int *count)
|
||||
{
|
||||
tBTA_GATTC_CLCB *p_clcb = bta_gattc_find_clcb_by_conn_id(conn_id);
|
||||
|
||||
|
||||
@@ -596,30 +596,6 @@ void bta_gattc_clear_notif_registration(tBTA_GATTC_SERV *p_srcb, UINT16 conn_id,
|
||||
return;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_clear_notif_registration_by_bda
|
||||
**
|
||||
** Description Clear up the notification registration information by BD_ADDR.
|
||||
**
|
||||
**
|
||||
** Returns None.
|
||||
**
|
||||
*******************************************************************************/
|
||||
void bta_gattc_clear_notif_registration_by_bda(tBTA_GATTC_RCB *p_clrcb, BD_ADDR remote_bda)
|
||||
{
|
||||
if(p_clrcb == NULL) {
|
||||
return;
|
||||
}
|
||||
for (uint8_t 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_gattc_mark_bg_conn
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include "stack/btm_ble_api.h"
|
||||
#include <string.h>
|
||||
#include "osi/allocator.h"
|
||||
#include "stack/l2c_api.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,
|
||||
@@ -673,7 +672,6 @@ void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
p_msg->api_indicate.len,
|
||||
p_msg->api_indicate.value);
|
||||
} else {
|
||||
l2ble_update_att_acl_pkt_num(L2CA_DECREASE_BTU_NUM, NULL);
|
||||
status = GATTS_HandleValueNotification (p_msg->api_indicate.hdr.layer_specific,
|
||||
p_msg->api_indicate.attr_id,
|
||||
p_msg->api_indicate.len,
|
||||
@@ -694,23 +692,16 @@ void bta_gatts_indicate_handle (tBTA_GATTS_CB *p_cb, tBTA_GATTS_DATA *p_msg)
|
||||
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;
|
||||
cb_data.req_data.value = NULL;
|
||||
cb_data.req_data.data_len = 0;
|
||||
cb_data.req_data.handle = p_msg->api_indicate.attr_id;
|
||||
|
||||
if (p_msg->api_indicate.value && (p_msg->api_indicate.len > 0)) {
|
||||
cb_data.req_data.value = (uint8_t *) osi_malloc(p_msg->api_indicate.len);
|
||||
if (cb_data.req_data.value != NULL) {
|
||||
memset(cb_data.req_data.value, 0, p_msg->api_indicate.len);
|
||||
cb_data.req_data.data_len = p_msg->api_indicate.len;
|
||||
memcpy(cb_data.req_data.value, p_msg->api_indicate.value, p_msg->api_indicate.len);
|
||||
} else {
|
||||
APPL_TRACE_ERROR("%s, malloc failed", __func__);
|
||||
}
|
||||
} else {
|
||||
if (p_msg->api_indicate.value) {
|
||||
APPL_TRACE_ERROR("%s, incorrect length", __func__);
|
||||
}
|
||||
cb_data.req_data.value = (uint8_t *)osi_malloc(p_msg->api_indicate.len);
|
||||
if (cb_data.req_data.value != NULL){
|
||||
memset(cb_data.req_data.value, 0, p_msg->api_indicate.len);
|
||||
cb_data.req_data.data_len = p_msg->api_indicate.len;
|
||||
memcpy(cb_data.req_data.value, p_msg->api_indicate.value, p_msg->api_indicate.len);
|
||||
}else{
|
||||
cb_data.req_data.data_len = 0;
|
||||
APPL_TRACE_ERROR("%s, malloc failed", __func__);
|
||||
}
|
||||
(*p_rcb->p_cback)(BTA_GATTS_CONF_EVT, &cb_data);
|
||||
if (cb_data.req_data.value != NULL) {
|
||||
@@ -1016,14 +1007,22 @@ static void bta_gatts_conn_cback (tGATT_IF gatt_if, BD_ADDR bda, UINT16 conn_id,
|
||||
** Returns none.
|
||||
**
|
||||
*******************************************************************************/
|
||||
extern void btc_congest_callback(tBTA_GATTS *param);
|
||||
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;
|
||||
|
||||
cb_data.congest.conn_id = conn_id;
|
||||
cb_data.congest.congested = congested;
|
||||
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);
|
||||
|
||||
btc_congest_callback(&cb_data);
|
||||
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 /* GATTS_INCLUDED */
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
#include "bta/bta_gatt_api.h"
|
||||
#include "bta_gatts_int.h"
|
||||
#include "osi/allocator.h"
|
||||
#include "stack/l2c_api.h"
|
||||
|
||||
/*****************************************************************************
|
||||
** Constants
|
||||
*****************************************************************************/
|
||||
@@ -76,7 +76,7 @@ void BTA_GATTS_Disable(void)
|
||||
** Description This function is called to register application callbacks
|
||||
** with BTA GATTS module.
|
||||
**
|
||||
** Parameters p_app_uuid - application UUID
|
||||
** Parameters p_app_uuid - applicaiton UUID
|
||||
** p_cback - pointer to the application callback function.
|
||||
**
|
||||
** Returns None
|
||||
@@ -347,7 +347,7 @@ void BTA_GATTS_DeleteService(UINT16 service_id)
|
||||
** Description This function is called to start a service.
|
||||
**
|
||||
** Parameters service_id: the service ID to be started.
|
||||
** sup_transport: supported transport.
|
||||
** sup_transport: supported trasnport.
|
||||
**
|
||||
** Returns None.
|
||||
**
|
||||
@@ -426,11 +426,6 @@ void BTA_GATTS_HandleValueIndication (UINT16 conn_id, UINT16 attr_id, UINT16 dat
|
||||
memcpy(p_buf->value, p_data, data_len);
|
||||
|
||||
}
|
||||
|
||||
if(need_confirm == false){
|
||||
l2ble_update_att_acl_pkt_num(L2CA_DECREASE_BTC_NUM, NULL);
|
||||
l2ble_update_att_acl_pkt_num(L2CA_ADD_BTU_NUM, NULL);
|
||||
}
|
||||
bta_sys_sendmsg(p_buf);
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -498,7 +498,6 @@ extern BOOLEAN bta_gattc_mark_bg_conn (tBTA_GATTC_IF client_if, BD_ADDR_PTR rem
|
||||
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(tBTA_GATTC_SERV *p_srcb, UINT16 conn_id, UINT16 start_handle, UINT16 end_handle);
|
||||
extern void bta_gattc_clear_notif_registration_by_bda(tBTA_GATTC_RCB *p_clrcb, BD_ADDR remote_bda);
|
||||
extern tBTA_GATTC_SERV * bta_gattc_find_srvr_cache(BD_ADDR bda);
|
||||
|
||||
/* discovery functions */
|
||||
@@ -512,12 +511,12 @@ extern const tBTA_GATTC_SERVICE* bta_gattc_get_service_for_handle(UINT16 conn_id
|
||||
tBTA_GATTC_CHARACTERISTIC* bta_gattc_get_characteristic_srcb(tBTA_GATTC_SERV *p_srcb, UINT16 handle);
|
||||
extern tBTA_GATTC_CHARACTERISTIC* bta_gattc_get_characteristic(UINT16 conn_id, UINT16 handle);
|
||||
extern tBTA_GATTC_DESCRIPTOR* bta_gattc_get_descriptor(UINT16 conn_id, UINT16 handle);
|
||||
extern void bta_gattc_get_db_size_handle(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, UINT16 *count);
|
||||
extern void bta_gattc_get_db_size_handle(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, int *count);
|
||||
extern void bta_gattc_get_db_size_with_type_handle(UINT16 conn_id, bt_gatt_db_attribute_type_t type,
|
||||
UINT16 start_handle, UINT16 end_handle, UINT16 char_handle, UINT16 *count);
|
||||
UINT16 start_handle, UINT16 end_handle, UINT16 char_handle, int *count);
|
||||
extern void bta_gattc_get_service_with_uuid(UINT16 conn_id, tBT_UUID *svc_uuid,
|
||||
btgatt_db_element_t **svc_db,
|
||||
UINT16 *count);
|
||||
int *count);
|
||||
|
||||
extern void bta_gattc_get_db_with_opration(UINT16 conn_id,
|
||||
bt_gatt_get_db_op_t op,
|
||||
@@ -527,9 +526,9 @@ extern void bta_gattc_get_db_with_opration(UINT16 conn_id,
|
||||
tBT_UUID *descr_uuid,
|
||||
UINT16 start_handle, UINT16 end_handle,
|
||||
btgatt_db_element_t **char_db,
|
||||
UINT16 *count);
|
||||
int *count);
|
||||
|
||||
extern void bta_gattc_get_gatt_db(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, btgatt_db_element_t **db, UINT16 *count);
|
||||
extern void bta_gattc_get_gatt_db(UINT16 conn_id, UINT16 start_handle, UINT16 end_handle, btgatt_db_element_t **db, int *count);
|
||||
|
||||
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 *attr);
|
||||
|
||||
@@ -141,7 +141,7 @@ void BTA_HfClientRegister(tBTA_SEC sec_mask, tBTA_HF_CLIENT_FEAT features,
|
||||
p_buf->features = features;
|
||||
p_buf->sec_mask = sec_mask;
|
||||
if (p_service_name) {
|
||||
BCM_STRNCPY_S(p_buf->name, p_service_name, BTA_SERVICE_NAME_LEN);
|
||||
BCM_STRNCPY_S(p_buf->name, BTA_SERVICE_NAME_LEN + 1, p_service_name, BTA_SERVICE_NAME_LEN);
|
||||
p_buf->name[BTA_SERVICE_NAME_LEN] = 0;
|
||||
} else {
|
||||
p_buf->name[0] = '\0';
|
||||
|
||||
@@ -75,12 +75,12 @@ typedef struct {
|
||||
/* CIND: storage room for indicators value range and their statuses */
|
||||
static const tBTA_HF_CLIENT_INDICATOR bta_hf_client_indicators[BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT] = {
|
||||
/* name | min | max | name length - used by parser */
|
||||
{BTA_HF_CLIENT_INDICATOR_CALL, 0, 1, sizeof(BTA_HF_CLIENT_INDICATOR_CALL)},
|
||||
{BTA_HF_CLIENT_INDICATOR_CALLSETUP, 0, 3, sizeof(BTA_HF_CLIENT_INDICATOR_CALLSETUP)},
|
||||
{BTA_HF_CLIENT_INDICATOR_SERVICE, 0, 1, sizeof(BTA_HF_CLIENT_INDICATOR_SERVICE)},
|
||||
{BTA_HF_CLIENT_INDICATOR_SIGNAL, 0, 5, sizeof(BTA_HF_CLIENT_INDICATOR_SIGNAL)},
|
||||
{BTA_HF_CLIENT_INDICATOR_ROAM, 0, 1, sizeof(BTA_HF_CLIENT_INDICATOR_ROAM)},
|
||||
{BTA_HF_CLIENT_INDICATOR_BATTERYCHG, 0, 5, sizeof(BTA_HF_CLIENT_INDICATOR_BATTERYCHG)},
|
||||
{BTA_HF_CLIENT_INDICATOR_SIGNAL, 0, 5, sizeof(BTA_HF_CLIENT_INDICATOR_SIGNAL)},
|
||||
{BTA_HF_CLIENT_INDICATOR_SERVICE, 0, 1, sizeof(BTA_HF_CLIENT_INDICATOR_SERVICE)},
|
||||
{BTA_HF_CLIENT_INDICATOR_CALL, 0, 1, sizeof(BTA_HF_CLIENT_INDICATOR_CALL)},
|
||||
{BTA_HF_CLIENT_INDICATOR_ROAM, 0, 1, sizeof(BTA_HF_CLIENT_INDICATOR_ROAM)},
|
||||
{BTA_HF_CLIENT_INDICATOR_CALLSETUP, 0, 3, sizeof(BTA_HF_CLIENT_INDICATOR_CALLSETUP)},
|
||||
{BTA_HF_CLIENT_INDICATOR_CALLHELD, 0, 2, sizeof(BTA_HF_CLIENT_INDICATOR_CALLHELD)}
|
||||
};
|
||||
|
||||
@@ -94,7 +94,7 @@ UINT32 service_index = 0;
|
||||
BOOLEAN service_availability = TRUE;
|
||||
/* helper functions for handling AT commands queueing */
|
||||
|
||||
static void bta_hf_client_handle_ok(void);
|
||||
static void bta_hf_client_handle_ok();
|
||||
|
||||
static void bta_hf_client_clear_queued_at(void)
|
||||
{
|
||||
@@ -268,7 +268,7 @@ static void bta_hf_client_start_at_hold_timer(void)
|
||||
** No buffer parsing is being done here.
|
||||
*******************************************************************************/
|
||||
|
||||
static void bta_hf_client_handle_ok(void)
|
||||
static void bta_hf_client_handle_ok()
|
||||
{
|
||||
APPL_TRACE_DEBUG("%s", __FUNCTION__);
|
||||
|
||||
@@ -342,7 +342,7 @@ static void bta_hf_client_handle_error(tBTA_HF_CLIENT_AT_RESULT_TYPE type, UINT1
|
||||
bta_hf_client_send_queued_at();
|
||||
}
|
||||
|
||||
static void bta_hf_client_handle_ring(void)
|
||||
static void bta_hf_client_handle_ring()
|
||||
{
|
||||
APPL_TRACE_DEBUG("%s", __FUNCTION__);
|
||||
bta_hf_client_evt_val(BTA_HF_CLIENT_RING_INDICATION, 0);
|
||||
@@ -427,7 +427,7 @@ static void bta_hf_client_handle_ciev(UINT32 index, UINT32 value)
|
||||
|
||||
APPL_TRACE_DEBUG("%s index: %u value: %u", __FUNCTION__, index, value);
|
||||
|
||||
if (index >= BTA_HF_CLIENT_AT_INDICATOR_COUNT) {
|
||||
if (index == 0 || index > BTA_HF_CLIENT_AT_INDICATOR_COUNT) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -435,7 +435,7 @@ static void bta_hf_client_handle_ciev(UINT32 index, UINT32 value)
|
||||
service_availability = value == 0 ? FALSE : TRUE;
|
||||
}
|
||||
|
||||
realind = bta_hf_client_cb.scb.at_cb.indicator_lookup[index];
|
||||
realind = bta_hf_client_cb.scb.at_cb.indicator_lookup[index - 1];
|
||||
|
||||
if (realind >= 0 && realind < BTA_HF_CLIENT_AT_SUPPORTED_INDICATOR_COUNT) {
|
||||
/* get the real in-array index from lookup table by index it comes at */
|
||||
@@ -576,17 +576,15 @@ static void bta_hf_client_handle_btrh( UINT16 code)
|
||||
|
||||
/* Check if prefix match and skip spaces if any */
|
||||
#define AT_CHECK_EVENT(buf, event) \
|
||||
if (strncmp("\r\n"event,buf,sizeof("\r\n"event) - 1) != 0) \
|
||||
return buf; \
|
||||
buf += sizeof("\r\n"event) - 1; \
|
||||
while (*buf == ' ') buf++;
|
||||
if (strncmp("\r\n"event, buf,sizeof("\r\n"event) - 1) != 0) return buf; \
|
||||
buf += sizeof("\r\n"event) - 1; \
|
||||
while (*buf == ' ') buf++;
|
||||
|
||||
/* check for <cr><lf> and forward buffer if match */
|
||||
#define AT_CHECK_RN(buf) \
|
||||
if (strncmp("\r\n", buf, sizeof("\r\n") - 1) != 0) { \
|
||||
APPL_TRACE_ERROR("%s missing end <cr><lf>", __FUNCTION__); \
|
||||
return NULL;\
|
||||
} \
|
||||
APPL_TRACE_DEBUG("%s missing end <cr><lf>", __FUNCTION__); \
|
||||
return NULL;} \
|
||||
buf += sizeof("\r\n") - 1;
|
||||
|
||||
/* skip rest of AT string up to <cr> */
|
||||
@@ -1024,20 +1022,20 @@ static char *bta_hf_client_parse_clcc(char *buffer)
|
||||
static char *bta_hf_client_parse_cnum(char *buffer)
|
||||
{
|
||||
char numstr[33]; /* spec forces 32 chars, plus one for \0*/
|
||||
int type;
|
||||
int service = 0; /* 0 in case this optional parameter is not being sent */
|
||||
UINT16 type;
|
||||
UINT16 service = 0; /* 0 in case this optional parameter is not being sent */
|
||||
int res;
|
||||
int offset;
|
||||
|
||||
AT_CHECK_EVENT(buffer, "+CNUM:");
|
||||
|
||||
res = sscanf(buffer, ",\"%32[^\"]\",%d%n,,%d%n", numstr, &type, &offset, &service, &offset);
|
||||
res = sscanf(buffer, ",\"%32[^\"]\",%hu,,%hu%n", numstr, &type, &service, &offset);
|
||||
if (res < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (res == 0) {
|
||||
res = sscanf(buffer, ",\"\",%d%n,,%d%n", &type, &offset, &service, &offset);
|
||||
res = sscanf(buffer, ",\"\",%hu,,%hu%n", &type, &service, &offset);
|
||||
if (res < 0) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -1047,7 +1045,7 @@ static char *bta_hf_client_parse_cnum(char *buffer)
|
||||
numstr[0] = '\0';
|
||||
}
|
||||
|
||||
if (res < 2) {
|
||||
if (res < 3) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1259,7 +1257,7 @@ static void bta_hf_client_at_parse_start(void)
|
||||
for (i = 0; i < bta_hf_client_psraser_cb_count; i++) {
|
||||
tmp = bta_hf_client_parser_cb[i](buf);
|
||||
if (tmp == NULL) {
|
||||
APPL_TRACE_ERROR("HFPCient: AT event/reply parsing failed, skipping %d", i);
|
||||
APPL_TRACE_ERROR("HFPCient: AT event/reply parsing failed, skipping");
|
||||
tmp = bta_hf_client_skip_unknown(buf);
|
||||
break;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user