Merge branch 'master' into mqb-long

# Conflicts:
#	opendbc
#	panda
#	selfdrive/car/volkswagen/carstate.py
pull/81/head
Jason Young 3 years ago
commit e229c4db71
  1. 13
      .github/workflows/selfdrive_tests.yaml
  2. 6
      .pre-commit-config.yaml
  3. 1
      Jenkinsfile
  4. 14
      RELEASES.md
  5. 1
      SConstruct
  6. 2
      cereal
  7. 4
      common/gpio.py
  8. 11
      common/realtime.py
  9. 3
      docs/CARS.md
  10. 2
      laika_repo
  11. 1
      launch_chffrplus.sh
  12. 4
      release/files_common
  13. 6
      scripts/launch_corolla.sh
  14. 8
      selfdrive/athena/athenad.py
  15. 4
      selfdrive/athena/registration.py
  16. 4
      selfdrive/boardd/boardd.cc
  17. 2
      selfdrive/boardd/panda.cc
  18. 2
      selfdrive/boardd/panda.h
  19. 10
      selfdrive/boardd/pandad.py
  20. 3
      selfdrive/car/honda/values.py
  21. 15
      selfdrive/car/hyundai/carstate.py
  22. 14
      selfdrive/car/hyundai/interface.py
  23. 4
      selfdrive/car/hyundai/values.py
  24. 5
      selfdrive/car/interfaces.py
  25. 36
      selfdrive/car/subaru/values.py
  26. 9
      selfdrive/car/tests/routes.py
  27. 16
      selfdrive/car/tests/test_fw_fingerprint.py
  28. 14
      selfdrive/car/tests/test_models.py
  29. 17
      selfdrive/car/toyota/carstate.py
  30. 8
      selfdrive/car/toyota/interface.py
  31. 8
      selfdrive/car/toyota/tunes.py
  32. 6
      selfdrive/car/toyota/values.py
  33. 7
      selfdrive/car/volkswagen/carstate.py
  34. 2
      selfdrive/car/volkswagen/interface.py
  35. 5
      selfdrive/car/volkswagen/values.py
  36. 2
      selfdrive/common/params.cc
  37. 2
      selfdrive/controls/controlsd.py
  38. 35
      selfdrive/controls/lib/events.py
  39. 6
      selfdrive/controls/lib/latcontrol_torque.py
  40. 5
      selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py
  41. 49
      selfdrive/debug/cycle_alerts.py
  42. 2
      selfdrive/debug/hyundai_enable_radar_points.py
  43. 3
      selfdrive/debug/internal/measure_modeld_packet_drop.py
  44. 9
      selfdrive/debug/live_cpu_and_temp.py
  45. 8
      selfdrive/hardware/base.py
  46. 2
      selfdrive/hardware/tici/agnos.py
  47. 33
      selfdrive/hardware/tici/hardware.py
  48. 3
      selfdrive/hardware/tici/pins.py
  49. 44
      selfdrive/hardware/tici/power_monitor.py
  50. 9
      selfdrive/hardware/tici/precise_power_measure.py
  51. 61
      selfdrive/hardware/tici/test_power_draw.py
  52. 8
      selfdrive/locationd/paramsd.py
  53. 2
      selfdrive/loggerd/SConscript
  54. 127
      selfdrive/loggerd/omx_encoder.cc
  55. 17
      selfdrive/loggerd/omx_encoder.h
  56. 115
      selfdrive/loggerd/raw_logger.cc
  57. 10
      selfdrive/loggerd/raw_logger.h
  58. 118
      selfdrive/loggerd/video_writer.cc
  59. 25
      selfdrive/loggerd/video_writer.h
  60. 2
      selfdrive/manager/build.py
  61. 8
      selfdrive/manager/manager.py
  62. 48
      selfdrive/manager/process.py
  63. 28
      selfdrive/manager/process_config.py
  64. 21
      selfdrive/modeld/modeld.cc
  65. 7
      selfdrive/modeld/models/driving.cc
  66. 2
      selfdrive/modeld/models/driving.h
  67. 5
      selfdrive/modeld/runners/onnx_runner.py
  68. 51
      selfdrive/modeld/test/test_modeld.py
  69. 2
      selfdrive/rtshield.py
  70. 1
      selfdrive/test/process_replay/process_replay.py
  71. 2
      selfdrive/test/process_replay/ref_commit
  72. 25
      selfdrive/test/process_replay/regen.py
  73. 8
      selfdrive/test/process_replay/test_processes.py
  74. 8
      selfdrive/test/test_onroad.py
  75. 2
      selfdrive/thermald/thermald.py
  76. 4
      selfdrive/ui/SConscript
  77. 2
      selfdrive/ui/qt/offroad/driverview.cc
  78. 6
      selfdrive/ui/qt/onroad.cc
  79. 143
      selfdrive/ui/qt/widgets/cameraview.cc
  80. 7
      selfdrive/ui/qt/widgets/cameraview.h
  81. 1
      selfdrive/ui/replay/main.cc
  82. 2
      selfdrive/ui/replay/replay.cc
  83. 1
      selfdrive/ui/replay/replay.h
  84. 30
      selfdrive/ui/ui.cc
  85. 9
      selfdrive/ui/watch3.cc
  86. 65
      selfdrive/updated.py
  87. 274
      third_party/boringssl/LICENSE
  88. 192
      third_party/boringssl/LICENSE.boringssl
  89. 7
      third_party/boringssl/build.txt
  90. 315
      third_party/boringssl/include/openssl/aead.h
  91. 158
      third_party/boringssl/include/openssl/aes.h
  92. 1234
      third_party/boringssl/include/openssl/asn1.h
  93. 76
      third_party/boringssl/include/openssl/asn1_mac.h
  94. 907
      third_party/boringssl/include/openssl/asn1t.h
  95. 233
      third_party/boringssl/include/openssl/base.h
  96. 179
      third_party/boringssl/include/openssl/base64.h
  97. 910
      third_party/boringssl/include/openssl/bio.h
  98. 93
      third_party/boringssl/include/openssl/blowfish.h
  99. 875
      third_party/boringssl/include/openssl/bn.h
  100. 123
      third_party/boringssl/include/openssl/buf.h
  101. Some files were not shown because too many files have changed in this diff Show More

@ -69,6 +69,19 @@ jobs:
rm -rf /tmp/scons_cache/* && \ rm -rf /tmp/scons_cache/* && \
scons -j$(nproc) --cache-populate" scons -j$(nproc) --cache-populate"
build_all:
name: build all
runs-on: ubuntu-20.04
timeout-minutes: 50
steps:
- uses: actions/checkout@v2
with:
submodules: true
- name: Build Docker image
run: eval "$BUILD"
- name: Build openpilot with all flags
run: ${{ env.RUN }} "scons -j$(nproc) --extras --test"
#build_mac: #build_mac:
# name: build macos # name: build macos
# runs-on: macos-latest # runs-on: macos-latest

@ -21,7 +21,11 @@ repos:
- id: mypy - id: mypy
exclude: '^(pyextra/)|(cereal/)|(rednose/)|(panda/)|(laika/)|(opendbc/)|(laika_repo/)|(rednose_repo/)/' exclude: '^(pyextra/)|(cereal/)|(rednose/)|(panda/)|(laika/)|(opendbc/)|(laika_repo/)|(rednose_repo/)/'
additional_dependencies: ['git+https://github.com/numpy/numpy-stubs', 'types-requests', 'types-atomicwrites', additional_dependencies: ['git+https://github.com/numpy/numpy-stubs', 'types-requests', 'types-atomicwrites',
'types-pycurl'] 'types-pycurl', 'types-certifi']
args:
- --warn-unused-ignores
- --warn-redundant-casts
- --warn-unreachable
- repo: https://github.com/PyCQA/flake8 - repo: https://github.com/PyCQA/flake8
rev: 4.0.1 rev: 4.0.1
hooks: hooks:

1
Jenkinsfile vendored

@ -120,6 +120,7 @@ pipeline {
steps { steps {
phone_steps("tici2", [ phone_steps("tici2", [
["build", "cd selfdrive/manager && ./build.py"], ["build", "cd selfdrive/manager && ./build.py"],
["test power draw", "python selfdrive/hardware/tici/test_power_draw.py"],
["test boardd loopback", "python selfdrive/boardd/tests/test_boardd_loopback.py"], ["test boardd loopback", "python selfdrive/boardd/tests/test_boardd_loopback.py"],
["test loggerd", "python selfdrive/loggerd/tests/test_loggerd.py"], ["test loggerd", "python selfdrive/loggerd/tests/test_loggerd.py"],
["test encoder", "LD_LIBRARY_PATH=/usr/local/lib python selfdrive/loggerd/tests/test_encoder.py"], ["test encoder", "LD_LIBRARY_PATH=/usr/local/lib python selfdrive/loggerd/tests/test_encoder.py"],

@ -1,7 +1,19 @@
Version 0.8.14 (2022-0X-XX) Version 0.8.14 (2022-0X-XX)
======================== ========================
* bigmodel! * New driving model
* Bigger model, using both of comma three's road-facing cameras
* Better at cut-in detection and tight turns
* New driver monitoring model
* Tweaked network structure to improve output resolution for dsp
* Fixed bug in quantization aware training to reduce quantizing errors
* Resulted in 7x less MSE and no more random biases at runtime
* New lateral controller based on physical wheel torque model
* Much smoother control, consistent across the speed range
* Effective feedforward that uses road roll
* Simplified tuning, all car specific parameters can be derived from data
* Initially used on TSS2 Corolla and TSS-P Rav4
* comma body support * comma body support
* Audi RS3 support thanks to jyoung8607!
* Hyundai Ioniq Plug-in Hybrid 2019 support thanks to sunnyhaibin! * Hyundai Ioniq Plug-in Hybrid 2019 support thanks to sunnyhaibin!
* Hyundai Tucson Diesel 2019 support thanks to sunnyhaibin! * Hyundai Tucson Diesel 2019 support thanks to sunnyhaibin!
* Toyota Alphard Hybrid 2021 support * Toyota Alphard Hybrid 2021 support

@ -183,7 +183,6 @@ env = Environment(
"#third_party/acados/include/blasfeo/include", "#third_party/acados/include/blasfeo/include",
"#third_party/acados/include/hpipm/include", "#third_party/acados/include/hpipm/include",
"#third_party/catch2/include", "#third_party/catch2/include",
"#third_party/bzip2",
"#third_party/libyuv/include", "#third_party/libyuv/include",
"#third_party/openmax/include", "#third_party/openmax/include",
"#third_party/json11", "#third_party/json11",

@ -1 +1 @@
Subproject commit 6eb3994daa0f64f57a36606a7bdd982ed2ac9d2d Subproject commit 29f4fe89ef710ff86a5aeb998a357187d0619fb8

@ -1,4 +1,4 @@
def gpio_init(pin, output): def gpio_init(pin: int, output: bool) -> None:
try: try:
with open(f"/sys/class/gpio/gpio{pin}/direction", 'wb') as f: with open(f"/sys/class/gpio/gpio{pin}/direction", 'wb') as f:
f.write(b"out" if output else b"in") f.write(b"out" if output else b"in")
@ -6,7 +6,7 @@ def gpio_init(pin, output):
print(f"Failed to set gpio {pin} direction: {e}") print(f"Failed to set gpio {pin} direction: {e}")
def gpio_set(pin, high): def gpio_set(pin: int, high: bool) -> None:
try: try:
with open(f"/sys/class/gpio/gpio{pin}/value", 'wb') as f: with open(f"/sys/class/gpio/gpio{pin}/value", 'wb') as f:
f.write(b"1" if high else b"0") f.write(b"1" if high else b"0")

@ -2,7 +2,7 @@
import gc import gc
import os import os
import time import time
from typing import Optional from typing import Optional, List, Union
from setproctitle import getproctitle # pylint: disable=no-name-in-module from setproctitle import getproctitle # pylint: disable=no-name-in-module
@ -38,15 +38,16 @@ def set_realtime_priority(level: int) -> None:
os.sched_setscheduler(0, os.SCHED_FIFO, os.sched_param(level)) # type: ignore[attr-defined] os.sched_setscheduler(0, os.SCHED_FIFO, os.sched_param(level)) # type: ignore[attr-defined]
def set_core_affinity(core: int) -> None: def set_core_affinity(cores: List[int]) -> None:
if not PC: if not PC:
os.sched_setaffinity(0, [core,]) # type: ignore[attr-defined] os.sched_setaffinity(0, cores)
def config_realtime_process(core: int, priority: int) -> None: def config_realtime_process(cores: Union[int, List[int]], priority: int) -> None:
gc.disable() gc.disable()
set_realtime_priority(priority) set_realtime_priority(priority)
set_core_affinity(core) c = cores if isinstance(cores, list) else [cores, ]
set_core_affinity(c)
class Ratekeeper: class Ratekeeper:

@ -77,6 +77,7 @@ How We Rate The Cars
|Audi|A3 Sportback e-tron 2017-18|ACC + Lane Assist|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>| |Audi|A3 Sportback e-tron 2017-18|ACC + Lane Assist|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|
|Audi|Q2 2018|ACC + Lane Assist|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>| |Audi|Q2 2018|ACC + Lane Assist|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|
|Audi|Q3 2020-21|ACC + Lane Assist|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>| |Audi|Q3 2020-21|ACC + Lane Assist|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|
|Audi|RS3 2018|ACC + Lane Assist|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|
|Audi|S3 2015-17|ACC + Lane Assist|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>| |Audi|S3 2015-17|ACC + Lane Assist|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|
|Genesis|G70 2018|All|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>| |Genesis|G70 2018|All|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|
|Genesis|G80 2018|All|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>| |Genesis|G80 2018|All|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|
@ -86,7 +87,7 @@ How We Rate The Cars
|Hyundai|Ioniq Hybrid 2020-22|SCC + LFA|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>| |Hyundai|Ioniq Hybrid 2020-22|SCC + LFA|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|
|Hyundai|Ioniq Plug-in Hybrid 2020-21|SCC + LKAS|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>| |Hyundai|Ioniq Plug-in Hybrid 2020-21|SCC + LKAS|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|
|Hyundai|Kona 2020|SCC + LKAS|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>| |Hyundai|Kona 2020|SCC + LKAS|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|
|Hyundai|Kona Electric 2018-19|SCC + LKAS|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>| |Hyundai|Kona Electric 2018-21|SCC + LKAS|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|
|Hyundai|Kona Hybrid 2020|SCC + LKAS|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>| |Hyundai|Kona Hybrid 2020|SCC + LKAS|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|
|Hyundai|Santa Fe 2021-22|All|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>| |Hyundai|Santa Fe 2021-22|All|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|
|Hyundai|Santa Fe Hybrid 2022|All|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>| |Hyundai|Santa Fe Hybrid 2022|All|<a href="#"><img valign="top" src="assets/icon-star-empty.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|<a href="#"><img valign="top" src="assets/icon-star-full.svg" width="22" /></a>|

@ -1 +1 @@
Subproject commit e47ba47de2ad62f3c31cfdffa5aa381557a45d08 Subproject commit 226adc655e1488474468a97ab4a7705aad7e5837

@ -62,7 +62,6 @@ function launch {
cd $BASEDIR cd $BASEDIR
echo "Restarting launch script ${LAUNCHER_LOCATION}" echo "Restarting launch script ${LAUNCHER_LOCATION}"
unset REQUIRED_NEOS_VERSION
unset AGNOS_VERSION unset AGNOS_VERSION
exec "${LAUNCHER_LOCATION}" exec "${LAUNCHER_LOCATION}"
else else

@ -301,6 +301,8 @@ selfdrive/loggerd/SConscript
selfdrive/loggerd/encoder.h selfdrive/loggerd/encoder.h
selfdrive/loggerd/omx_encoder.cc selfdrive/loggerd/omx_encoder.cc
selfdrive/loggerd/omx_encoder.h selfdrive/loggerd/omx_encoder.h
selfdrive/loggerd/video_writer.cc
selfdrive/loggerd/video_writer.h
selfdrive/loggerd/logger.cc selfdrive/loggerd/logger.cc
selfdrive/loggerd/logger.h selfdrive/loggerd/logger.h
selfdrive/loggerd/loggerd.cc selfdrive/loggerd/loggerd.cc
@ -442,8 +444,6 @@ third_party/SConscript
third_party/linux/** third_party/linux/**
third_party/opencl/** third_party/opencl/**
third_party/zlib/*
third_party/bzip2/*
third_party/openmax/** third_party/openmax/**
third_party/json11/json11.cpp third_party/json11/json11.cpp

@ -0,0 +1,6 @@
#!/usr/bin/bash
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
export FINGERPRINT="TOYOTA COROLLA TSS2 2019"
$DIR/../launch_openpilot.sh

@ -255,12 +255,12 @@ def getMessage(service=None, timeout=1000):
@dispatcher.add_method @dispatcher.add_method
def getVersion(): def getVersion() -> Dict[str, str]:
return { return {
"version": get_version(), "version": get_version(),
"remote": get_origin(), "remote": get_origin(''),
"branch": get_short_branch(), "branch": get_short_branch(''),
"commit": get_commit(), "commit": get_commit(default=''),
} }

@ -3,6 +3,7 @@ import time
import json import json
import jwt import jwt
from pathlib import Path from pathlib import Path
from typing import Optional
from datetime import datetime, timedelta from datetime import datetime, timedelta
from common.api import api_get from common.api import api_get
@ -48,7 +49,8 @@ def register(show_spinner=False) -> str:
# Block until we get the imei # Block until we get the imei
serial = HARDWARE.get_serial() serial = HARDWARE.get_serial()
start_time = time.monotonic() start_time = time.monotonic()
imei1, imei2 = None, None imei1: Optional[str] = None
imei2: Optional[str] = None
while imei1 is None and imei2 is None: while imei1 is None and imei2 is None:
try: try:
imei1, imei2 = HARDWARE.get_imei(0), HARDWARE.get_imei(1) imei1, imei2 = HARDWARE.get_imei(0), HARDWARE.get_imei(1)

@ -156,7 +156,7 @@ bool safety_setter_thread(std::vector<Panda *> pandas) {
capnp::FlatArrayMessageReader cmsg(aligned_buf.align(params.data(), params.size())); capnp::FlatArrayMessageReader cmsg(aligned_buf.align(params.data(), params.size()));
cereal::CarParams::Reader car_params = cmsg.getRoot<cereal::CarParams>(); cereal::CarParams::Reader car_params = cmsg.getRoot<cereal::CarParams>();
cereal::CarParams::SafetyModel safety_model; cereal::CarParams::SafetyModel safety_model;
int safety_param; uint32_t safety_param;
auto safety_configs = car_params.getSafetyConfigs(); auto safety_configs = car_params.getSafetyConfigs();
uint16_t alternative_experience = car_params.getAlternativeExperience(); uint16_t alternative_experience = car_params.getAlternativeExperience();
@ -169,7 +169,7 @@ bool safety_setter_thread(std::vector<Panda *> pandas) {
} else { } else {
// If no safety mode is specified, default to silent // If no safety mode is specified, default to silent
safety_model = cereal::CarParams::SafetyModel::SILENT; safety_model = cereal::CarParams::SafetyModel::SILENT;
safety_param = 0; safety_param = 0U;
} }
LOGW("panda %d: setting safety model: %d, param: %d, alternative experience: %d", i, (int)safety_model, safety_param, alternative_experience); LOGW("panda %d: setting safety model: %d, param: %d, alternative experience: %d", i, (int)safety_model, safety_param, alternative_experience);

@ -247,7 +247,7 @@ int Panda::usb_bulk_read(unsigned char endpoint, unsigned char* data, int length
return transferred; return transferred;
} }
void Panda::set_safety_model(cereal::CarParams::SafetyModel safety_model, int safety_param) { void Panda::set_safety_model(cereal::CarParams::SafetyModel safety_model, uint32_t safety_param) {
usb_write(0xdc, (uint16_t)safety_model, safety_param); usb_write(0xdc, (uint16_t)safety_model, safety_param);
} }

@ -73,7 +73,7 @@ class Panda {
// Panda functionality // Panda functionality
cereal::PandaState::PandaType get_hw_type(); cereal::PandaState::PandaType get_hw_type();
void set_safety_model(cereal::CarParams::SafetyModel safety_model, int safety_param=0); void set_safety_model(cereal::CarParams::SafetyModel safety_model, uint32_t safety_param=0U);
void set_alternative_experience(uint16_t alternative_experience); void set_alternative_experience(uint16_t alternative_experience);
void set_rtc(struct tm sys_time); void set_rtc(struct tm sys_time);
struct tm get_rtc(); struct tm get_rtc();

@ -10,6 +10,7 @@ from functools import cmp_to_key
from panda import DEFAULT_FW_FN, DEFAULT_H7_FW_FN, MCU_TYPE_H7, Panda, PandaDFU from panda import DEFAULT_FW_FN, DEFAULT_H7_FW_FN, MCU_TYPE_H7, Panda, PandaDFU
from common.basedir import BASEDIR from common.basedir import BASEDIR
from common.params import Params from common.params import Params
from selfdrive.hardware import HARDWARE
from selfdrive.swaglog import cloudlog from selfdrive.swaglog import cloudlog
@ -27,6 +28,7 @@ def flash_panda(panda_serial: str) -> Panda:
panda = Panda(panda_serial) panda = Panda(panda_serial)
fw_signature = get_expected_signature(panda) fw_signature = get_expected_signature(panda)
internal_panda = panda.is_internal() and not panda.bootstub
panda_version = "bootstub" if panda.bootstub else panda.get_version() panda_version = "bootstub" if panda.bootstub else panda.get_version()
panda_signature = b"" if panda.bootstub else panda.get_signature() panda_signature = b"" if panda.bootstub else panda.get_signature()
@ -40,7 +42,9 @@ def flash_panda(panda_serial: str) -> Panda:
if panda.bootstub: if panda.bootstub:
bootstub_version = panda.get_version() bootstub_version = panda.get_version()
cloudlog.info(f"Flashed firmware not booting, flashing development bootloader. Bootstub version: {bootstub_version}") cloudlog.info(f"Flashed firmware not booting, flashing development bootloader. Bootstub version: {bootstub_version}")
panda.recover() if internal_panda:
HARDWARE.recover_internal_panda()
panda.recover(reset=(not internal_panda))
cloudlog.info("Done flashing bootloader") cloudlog.info("Done flashing bootloader")
if panda.bootstub: if panda.bootstub:
@ -89,6 +93,10 @@ def main() -> NoReturn:
panda_serials = Panda.list() panda_serials = Panda.list()
if len(panda_serials) == 0: if len(panda_serials) == 0:
if first_run:
cloudlog.info("Resetting internal panda")
HARDWARE.reset_internal_panda()
time.sleep(2) # wait to come back up
continue continue
cloudlog.info(f"{len(panda_serials)} panda(s) found, connecting - {panda_serials}") cloudlog.info(f"{len(panda_serials)} panda(s) found, connecting - {panda_serials}")

@ -1118,12 +1118,14 @@ FW_VERSIONS = {
CAR.PASSPORT: { CAR.PASSPORT: {
(Ecu.programmedFuelInjection, 0x18da10f1, None): [ (Ecu.programmedFuelInjection, 0x18da10f1, None): [
b'37805-RLV-B220\x00\x00', b'37805-RLV-B220\x00\x00',
b'37805-RLV-B210\x00\x00',
], ],
(Ecu.eps, 0x18da30f1, None): [ (Ecu.eps, 0x18da30f1, None): [
b'39990-TGS-A230\x00\x00', b'39990-TGS-A230\x00\x00',
], ],
(Ecu.fwdRadar, 0x18dab0f1, None): [ (Ecu.fwdRadar, 0x18dab0f1, None): [
b'36161-TGS-A030\x00\x00', b'36161-TGS-A030\x00\x00',
b'36161-TGS-A130\x00\x00',
], ],
(Ecu.gateway, 0x18daeff1, None): [ (Ecu.gateway, 0x18daeff1, None): [
b'38897-TG7-A040\x00\x00', b'38897-TG7-A040\x00\x00',
@ -1139,6 +1141,7 @@ FW_VERSIONS = {
], ],
(Ecu.combinationMeter, 0x18da60f1, None): [ (Ecu.combinationMeter, 0x18da60f1, None): [
b'78109-TGS-AT20\x00\x00', b'78109-TGS-AT20\x00\x00',
b'78109-TGS-AX20\x00\x00',
], ],
(Ecu.vsa, 0x18da28f1, None): [ (Ecu.vsa, 0x18da28f1, None): [
b'57114-TGS-A530\x00\x00', b'57114-TGS-A530\x00\x00',

@ -1,17 +1,24 @@
from collections import deque
import copy import copy
from cereal import car from cereal import car
from common.conversions import Conversions as CV from common.conversions import Conversions as CV
from opendbc.can.parser import CANParser from opendbc.can.parser import CANParser
from opendbc.can.can_define import CANDefine from opendbc.can.can_define import CANDefine
from selfdrive.car.hyundai.values import DBC, STEER_THRESHOLD, FEATURES, EV_CAR, HYBRID_CAR from selfdrive.car.hyundai.values import DBC, STEER_THRESHOLD, FEATURES, EV_CAR, HYBRID_CAR, Buttons
from selfdrive.car.interfaces import CarStateBase from selfdrive.car.interfaces import CarStateBase
PREV_BUTTON_SAMPLES = 4
class CarState(CarStateBase): class CarState(CarStateBase):
def __init__(self, CP): def __init__(self, CP):
super().__init__(CP) super().__init__(CP)
can_define = CANDefine(DBC[CP.carFingerprint]["pt"]) can_define = CANDefine(DBC[CP.carFingerprint]["pt"])
self.cruise_buttons = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES)
self.main_buttons = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES)
if self.CP.carFingerprint in FEATURES["use_cluster_gears"]: if self.CP.carFingerprint in FEATURES["use_cluster_gears"]:
self.shifter_values = can_define.dv["CLU15"]["CF_Clu_Gear"] self.shifter_values = can_define.dv["CLU15"]["CF_Clu_Gear"]
elif self.CP.carFingerprint in FEATURES["use_tcu_gears"]: elif self.CP.carFingerprint in FEATURES["use_tcu_gears"]:
@ -19,7 +26,6 @@ class CarState(CarStateBase):
else: # preferred and elect gear methods use same definition else: # preferred and elect gear methods use same definition
self.shifter_values = can_define.dv["LVR12"]["CF_Lvr_Gear"] self.shifter_values = can_define.dv["LVR12"]["CF_Lvr_Gear"]
def update(self, cp, cp_cam): def update(self, cp, cp_cam):
ret = car.CarState.new_message() ret = car.CarState.new_message()
@ -108,8 +114,9 @@ class CarState(CarStateBase):
self.clu11 = copy.copy(cp.vl["CLU11"]) self.clu11 = copy.copy(cp.vl["CLU11"])
self.steer_state = cp.vl["MDPS12"]["CF_Mdps_ToiActive"] # 0 NOT ACTIVE, 1 ACTIVE self.steer_state = cp.vl["MDPS12"]["CF_Mdps_ToiActive"] # 0 NOT ACTIVE, 1 ACTIVE
self.brake_error = cp.vl["TCS13"]["ACCEnable"] != 0 # 0 ACC CONTROL ENABLED, 1-3 ACC CONTROL DISABLED self.brake_error = cp.vl["TCS13"]["ACCEnable"] != 0 # 0 ACC CONTROL ENABLED, 1-3 ACC CONTROL DISABLED
self.prev_cruise_buttons = self.cruise_buttons self.prev_cruise_buttons = self.cruise_buttons[-1]
self.cruise_buttons = cp.vl["CLU11"]["CF_Clu_CruiseSwState"] self.cruise_buttons.extend(cp.vl_all["CLU11"]["CF_Clu_CruiseSwState"])
self.main_buttons.extend(cp.vl_all["CLU11"]["CF_Clu_CruiseSwMain"])
return ret return ret

@ -10,6 +10,8 @@ from selfdrive.car.disable_ecu import disable_ecu
ButtonType = car.CarState.ButtonEvent.Type ButtonType = car.CarState.ButtonEvent.Type
EventName = car.CarEvent.EventName EventName = car.CarEvent.EventName
ENABLE_BUTTONS = (Buttons.RES_ACCEL, Buttons.SET_DECEL, Buttons.CANCEL)
class CarInterface(CarInterfaceBase): class CarInterface(CarInterfaceBase):
@staticmethod @staticmethod
@ -315,7 +317,11 @@ class CarInterface(CarInterfaceBase):
ret = self.CS.update(self.cp, self.cp_cam) ret = self.CS.update(self.cp, self.cp_cam)
ret.steeringRateLimited = self.CC.steer_rate_limited if self.CC is not None else False ret.steeringRateLimited = self.CC.steer_rate_limited if self.CC is not None else False
events = self.create_common_events(ret, pcm_enable=self.CS.CP.pcmCruise) # On some newer model years, the CANCEL button acts as a pause/resume button based on the PCM state
# To avoid re-engaging when openpilot cancels, check user engagement intention via buttons
# Main button also can trigger an engagement on these cars
allow_enable = any(btn in ENABLE_BUTTONS for btn in self.CS.cruise_buttons) or any(self.CS.main_buttons)
events = self.create_common_events(ret, pcm_enable=self.CS.CP.pcmCruise, allow_enable=allow_enable)
if self.CS.brake_error: if self.CS.brake_error:
events.add(EventName.brakeUnavailable) events.add(EventName.brakeUnavailable)
@ -323,12 +329,12 @@ class CarInterface(CarInterfaceBase):
if self.CS.CP.openpilotLongitudinalControl: if self.CS.CP.openpilotLongitudinalControl:
buttonEvents = [] buttonEvents = []
if self.CS.cruise_buttons != self.CS.prev_cruise_buttons: if self.CS.cruise_buttons[-1] != self.CS.prev_cruise_buttons:
be = car.CarState.ButtonEvent.new_message() be = car.CarState.ButtonEvent.new_message()
be.type = ButtonType.unknown be.type = ButtonType.unknown
if self.CS.cruise_buttons != 0: if self.CS.cruise_buttons[-1] != 0:
be.pressed = True be.pressed = True
but = self.CS.cruise_buttons but = self.CS.cruise_buttons[-1]
else: else:
be.pressed = False be.pressed = False
but = self.CS.prev_cruise_buttons but = self.CS.prev_cruise_buttons

@ -93,8 +93,8 @@ CAR_INFO: Dict[str, Union[HyundaiCarInfo, List[HyundaiCarInfo]]] = {
CAR.IONIQ_PHEV_2019: HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2019", "SCC + LKAS"), CAR.IONIQ_PHEV_2019: HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2019", "SCC + LKAS"),
CAR.IONIQ_PHEV: HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2020-21"), CAR.IONIQ_PHEV: HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2020-21"),
CAR.KONA: HyundaiCarInfo("Hyundai Kona 2020"), CAR.KONA: HyundaiCarInfo("Hyundai Kona 2020"),
CAR.KONA_EV: HyundaiCarInfo("Hyundai Kona Electric 2018-19"), CAR.KONA_EV: HyundaiCarInfo("Hyundai Kona Electric 2018-21"),
CAR.KONA_HEV: HyundaiCarInfo("Hyundai Kona Hybrid 2020", video_link="https://youtu.be/_EdYQtV52-c"), CAR.KONA_HEV: HyundaiCarInfo("Hyundai Kona Hybrid 2020"),
CAR.SANTA_FE: HyundaiCarInfo("Hyundai Santa Fe 2019-20", "All"), CAR.SANTA_FE: HyundaiCarInfo("Hyundai Santa Fe 2019-20", "All"),
CAR.SANTA_FE_2022: HyundaiCarInfo("Hyundai Santa Fe 2021-22", "All"), CAR.SANTA_FE_2022: HyundaiCarInfo("Hyundai Santa Fe 2021-22", "All"),
CAR.SANTA_FE_HEV_2022: HyundaiCarInfo("Hyundai Santa Fe Hybrid 2022", "All"), CAR.SANTA_FE_HEV_2022: HyundaiCarInfo("Hyundai Santa Fe Hybrid 2022", "All"),

@ -131,7 +131,7 @@ class CarInterfaceBase(ABC):
def apply(self, c: car.CarControl) -> Tuple[car.CarControl.Actuators, List[bytes]]: def apply(self, c: car.CarControl) -> Tuple[car.CarControl.Actuators, List[bytes]]:
pass pass
def create_common_events(self, cs_out, extra_gears=None, pcm_enable=True): def create_common_events(self, cs_out, extra_gears=None, pcm_enable=True, allow_enable=True):
events = Events() events = Events()
if cs_out.doorOpen: if cs_out.doorOpen:
@ -175,8 +175,9 @@ class CarInterfaceBase(ABC):
events.add(EventName.steerUnavailable) events.add(EventName.steerUnavailable)
# we engage when pcm is active (rising edge) # we engage when pcm is active (rising edge)
# enabling can optionally be blocked by the car interface
if pcm_enable: if pcm_enable:
if cs_out.cruiseState.enabled and not self.CS.out.cruiseState.enabled: if cs_out.cruiseState.enabled and not self.CS.out.cruiseState.enabled and allow_enable:
events.add(EventName.pcmEnable) events.add(EventName.pcmEnable)
elif not cs_out.cruiseState.enabled: elif not cs_out.cruiseState.enabled:
events.add(EventName.pcmDisable) events.add(EventName.pcmDisable)

@ -122,9 +122,6 @@ FW_VERSIONS = {
b'\x00\x00c\xf4\x00\x00\x00\x00', b'\x00\x00c\xf4\x00\x00\x00\x00',
b'\x00\x00d\xdc\x00\x00\x00\x00', b'\x00\x00d\xdc\x00\x00\x00\x00',
], ],
(Ecu.fwdCamera, 0x7c4, None): [
b'\xf1\x00\xac\x02\x00',
],
(Ecu.engine, 0x7e0, None): [ (Ecu.engine, 0x7e0, None): [
b'\xaa\x61\x66\x73\x07', b'\xaa\x61\x66\x73\x07',
b'\xbeacr\a', b'\xbeacr\a',
@ -167,14 +164,19 @@ FW_VERSIONS = {
b'\xa2 \0313\000', b'\xa2 \0313\000',
b'\xa2 !i\000', b'\xa2 !i\000',
b'\xa2 !`\000', b'\xa2 !`\000',
b'\xf1\x00\xb2\x06\x04',
b'\xa2 `\x00',
], ],
(Ecu.eps, 0x746, None): [ (Ecu.eps, 0x746, None): [
b'\x9a\xc0\000\000', b'\x9a\xc0\000\000',
b'\n\xc0\004\000', b'\n\xc0\004\000',
b'\x9a\xc0\x04\x00',
], ],
(Ecu.fwdCamera, 0x787, None): [ (Ecu.fwdCamera, 0x787, None): [
b'\000\000eb\037@ \"', b'\000\000eb\037@ \"',
b'\000\000e\x8f\037@ )', b'\000\000e\x8f\037@ )',
b'\x00\x00eq\x1f@ "',
b'\x00\x00eq\x00\x00\x00\x00',
], ],
(Ecu.engine, 0x7e0, None): [ (Ecu.engine, 0x7e0, None): [
b'\xca!ap\a', b'\xca!ap\a',
@ -182,43 +184,52 @@ FW_VERSIONS = {
b'\xca!`0\a', b'\xca!`0\a',
b'\xcc\"f0\a', b'\xcc\"f0\a',
b'\xcc!fp\a', b'\xcc!fp\a',
b'\xf1\x00\xa2\x10\t',
b'\xca!f@\x07',
b'\xca!fp\x07',
], ],
(Ecu.transmission, 0x7e1, None): [ (Ecu.transmission, 0x7e1, None): [
b'\xe6\xf5\004\000\000', b'\xe6\xf5\004\000\000',
b'\xe6\xf5$\000\000', b'\xe6\xf5$\000\000',
b'\xe7\xf6B0\000', b'\xe7\xf6B0\000',
b'\xe7\xf5D0\000', b'\xe7\xf5D0\000',
b'\xf1\x00\xd7\x10@',
b'\xe6\xf5D0\x00',
], ],
}, },
CAR.FORESTER: { CAR.FORESTER: {
(Ecu.esp, 0x7b0, None): [ (Ecu.esp, 0x7b0, None): [
b'\xa3 \030\024\000', b'\xa3 \x18\x14\x00',
b'\xa3 \024\000', b'\xa3 \024\000',
b'\xa3 \031\024\000', b'\xa3 \031\024\000',
b'\xa3 \024\001', b'\xa3 \x14\x01',
b'\xf1\x00\xbb\r\x05',
], ],
(Ecu.eps, 0x746, None): [ (Ecu.eps, 0x746, None): [
b'\x8d\xc0\004\000', b'\x8d\xc0\x04\x00',
], ],
(Ecu.fwdCamera, 0x787, None): [ (Ecu.fwdCamera, 0x787, None): [
b'\000\000e!\037@ \021', b'\x00\x00e!\x1f@ \x11',
b'\000\000e\x97\037@ 0', b'\x00\x00e\x97\x1f@ 0',
b'\000\000e`\037@ ', b'\000\000e`\037@ ',
b'\xf1\x00\xac\x02\x00', b'\xf1\x00\xac\x02\x00',
b'\x00\x00e!\x00\x00\x00\x00',
b'\x00\x00e\x97\x00\x00\x00\x00',
], ],
(Ecu.engine, 0x7e0, None): [ (Ecu.engine, 0x7e0, None): [
b'\xb6\"`A\a', b'\xb6"`A\x07',
b'\xcf"`0\a', b'\xcf"`0\x07',
b'\xcb\"`@\a', b'\xcb\"`@\a',
b'\xcb\"`p\a', b'\xcb\"`p\a',
b'\xf1\x00\xa2\x10\n', b'\xf1\x00\xa2\x10\n',
], ],
(Ecu.transmission, 0x7e1, None): [ (Ecu.transmission, 0x7e1, None): [
b'\032\xf6B0\000', b'\032\xf6B0\000',
b'\032\xf6F`\000', b'\x1a\xf6F`\x00',
b'\032\xf6b`\000', b'\032\xf6b`\000',
b'\032\xf6B`\000', b'\x1a\xf6B`\x00',
b'\xf1\x00\xa4\x10@', b'\xf1\x00\xa4\x10@',
b'\x1a\xf6b0\x00',
], ],
}, },
CAR.FORESTER_PREGLOBAL: { CAR.FORESTER_PREGLOBAL: {
@ -247,6 +258,7 @@ FW_VERSIONS = {
b'\xda\xfd\xe0\x80\x00', b'\xda\xfd\xe0\x80\x00',
b'\xdc\xf2`\x81\000', b'\xdc\xf2`\x81\000',
b'\xdc\xf2`\x80\x00', b'\xdc\xf2`\x80\x00',
b'\x1a\xf6F`\x00',
], ],
}, },
CAR.LEGACY_PREGLOBAL: { CAR.LEGACY_PREGLOBAL: {

@ -48,8 +48,6 @@ routes = [
TestRoute("0e7a2ba168465df5|2020-10-18--14-14-22", HONDA.ACURA_RDX_3G), TestRoute("0e7a2ba168465df5|2020-10-18--14-14-22", HONDA.ACURA_RDX_3G),
TestRoute("a74b011b32b51b56|2020-07-26--17-09-36", HONDA.CIVIC), TestRoute("a74b011b32b51b56|2020-07-26--17-09-36", HONDA.CIVIC),
# Checks there's no controls mismatches due to pedal thresholds
TestRoute("cfb32f0fb91b173b|2022-04-06--14-54-45", HONDA.CIVIC, segment=21),
TestRoute("a859a044a447c2b0|2020-03-03--18-42-45", HONDA.CRV_EU), TestRoute("a859a044a447c2b0|2020-03-03--18-42-45", HONDA.CRV_EU),
TestRoute("68aac44ad69f838e|2021-05-18--20-40-52", HONDA.CRV), TestRoute("68aac44ad69f838e|2021-05-18--20-40-52", HONDA.CRV),
TestRoute("14fed2e5fa0aa1a5|2021-05-25--14-59-42", HONDA.CRV_HYBRID), TestRoute("14fed2e5fa0aa1a5|2021-05-25--14-59-42", HONDA.CRV_HYBRID),
@ -207,4 +205,11 @@ routes = [
TestRoute("6c14ee12b74823ce|2021-06-30--11-49-02", TESLA.AP1_MODELS), TestRoute("6c14ee12b74823ce|2021-06-30--11-49-02", TESLA.AP1_MODELS),
TestRoute("bb50caf5f0945ab1|2021-06-19--17-20-18", TESLA.AP2_MODELS), TestRoute("bb50caf5f0945ab1|2021-06-19--17-20-18", TESLA.AP2_MODELS),
# Segments that test specific issues
# Controls mismatch due to interceptor threshold
TestRoute("cfb32f0fb91b173b|2022-04-06--14-54-45", HONDA.CIVIC, segment=21),
TestRoute("5a8762b91fc70467|2022-04-14--21-26-20", TOYOTA.RAV4, segment=2),
# Controls mismatch due to standstill threshold
TestRoute("bec2dcfde6a64235|2022-04-08--14-21-32", HONDA.CRV_HYBRID, segment=22),
] ]

@ -4,6 +4,7 @@ import unittest
from parameterized import parameterized from parameterized import parameterized
from cereal import car from cereal import car
from selfdrive.car.car_helpers import interfaces
from selfdrive.car.fingerprints import FW_VERSIONS from selfdrive.car.fingerprints import FW_VERSIONS
from selfdrive.car.fw_versions import match_fw_to_car from selfdrive.car.fw_versions import match_fw_to_car
@ -12,6 +13,7 @@ Ecu = car.CarParams.Ecu
ECU_NAME = {v: k for k, v in Ecu.schema.enumerants.items()} ECU_NAME = {v: k for k, v in Ecu.schema.enumerants.items()}
class TestFwFingerprint(unittest.TestCase): class TestFwFingerprint(unittest.TestCase):
def assertFingerprints(self, candidates, expected): def assertFingerprints(self, candidates, expected):
candidates = list(candidates) candidates = list(candidates)
@ -42,5 +44,19 @@ class TestFwFingerprint(unittest.TestCase):
self.assertTrue(passed, "Duplicate FW versions found") self.assertTrue(passed, "Duplicate FW versions found")
def test_blacklisted_ecus(self):
passed = True
blacklisted_addrs = (0x7c4, 0x7d0) # includes A/C ecu and an unknown ecu
for car_model, ecus in FW_VERSIONS.items():
CP = interfaces[car_model][0].get_params(car_model)
if CP.carName == 'subaru':
for ecu in ecus.keys():
if ecu[1] in blacklisted_addrs:
print(f'{car_model}: Blacklisted ecu: (Ecu.{ECU_NAME[ecu[0]]}, {hex(ecu[1])})')
passed = False
self.assertTrue(passed, "Blacklisted FW versions found")
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()

@ -15,7 +15,6 @@ from selfdrive.car.car_helpers import interfaces
from selfdrive.car.gm.values import CAR as GM from selfdrive.car.gm.values import CAR as GM
from selfdrive.car.honda.values import CAR as HONDA, HONDA_BOSCH from selfdrive.car.honda.values import CAR as HONDA, HONDA_BOSCH
from selfdrive.car.hyundai.values import CAR as HYUNDAI from selfdrive.car.hyundai.values import CAR as HYUNDAI
from selfdrive.car.toyota.values import CAR as TOYOTA
from selfdrive.car.tests.routes import non_tested_cars, routes, TestRoute from selfdrive.car.tests.routes import non_tested_cars, routes, TestRoute
from selfdrive.test.openpilotci import get_url from selfdrive.test.openpilotci import get_url
from tools.lib.logreader import LogReader from tools.lib.logreader import LogReader
@ -209,13 +208,7 @@ class TestCarModel(unittest.TestCase):
# TODO: check rest of panda's carstate (steering, ACC main on, etc.) # TODO: check rest of panda's carstate (steering, ACC main on, etc.)
# TODO: make the interceptor thresholds in openpilot and panda match, then remove this exception checks['gasPressed'] += CS.gasPressed != self.safety.get_gas_pressed_prev()
gas_pressed = CS.gasPressed
if self.CP.enableGasInterceptor and gas_pressed and not self.safety.get_gas_pressed_prev():
# panda intentionally has a higher threshold
if self.CP.carName == "toyota" and 15 < CS.gas < 15*1.5:
gas_pressed = False
checks['gasPressed'] += gas_pressed != self.safety.get_gas_pressed_prev()
# TODO: remove this exception once this mismatch is resolved # TODO: remove this exception once this mismatch is resolved
brake_pressed = CS.brakePressed brake_pressed = CS.brakePressed
@ -250,12 +243,9 @@ class TestCarModel(unittest.TestCase):
CS_prev = CS CS_prev = CS
# TODO: add flag to toyota safety
if self.CP.carFingerprint == TOYOTA.SIENNA and checks['brakePressed'] < 25:
checks['brakePressed'] = 0
failed_checks = {k: v for k, v in checks.items() if v > 0} failed_checks = {k: v for k, v in checks.items() if v > 0}
self.assertFalse(len(failed_checks), f"panda safety doesn't agree with openpilot: {failed_checks}") self.assertFalse(len(failed_checks), f"panda safety doesn't agree with openpilot: {failed_checks}")
if __name__ == "__main__": if __name__ == "__main__":
unittest.main() unittest.main()

@ -36,8 +36,8 @@ class CarState(CarStateBase):
ret.brakePressed = cp.vl["BRAKE_MODULE"]["BRAKE_PRESSED"] != 0 ret.brakePressed = cp.vl["BRAKE_MODULE"]["BRAKE_PRESSED"] != 0
ret.brakeHoldActive = cp.vl["ESP_CONTROL"]["BRAKE_HOLD_ACTIVE"] == 1 ret.brakeHoldActive = cp.vl["ESP_CONTROL"]["BRAKE_HOLD_ACTIVE"] == 1
if self.CP.enableGasInterceptor: if self.CP.enableGasInterceptor:
ret.gas = (cp.vl["GAS_SENSOR"]["INTERCEPTOR_GAS"] + cp.vl["GAS_SENSOR"]["INTERCEPTOR_GAS2"]) / 2. ret.gas = (cp.vl["GAS_SENSOR"]["INTERCEPTOR_GAS"] + cp.vl["GAS_SENSOR"]["INTERCEPTOR_GAS2"]) // 2
ret.gasPressed = ret.gas > 15 ret.gasPressed = ret.gas > 805
else: else:
# TODO: find a new, common signal # TODO: find a new, common signal
msg = "GAS_PEDAL_HYBRID" if (self.CP.flags & ToyotaFlags.HYBRID) else "GAS_PEDAL" msg = "GAS_PEDAL_HYBRID" if (self.CP.flags & ToyotaFlags.HYBRID) else "GAS_PEDAL"
@ -115,6 +115,9 @@ class CarState(CarStateBase):
ret.genericToggle = bool(cp.vl["LIGHT_STALK"]["AUTO_HIGH_BEAM"]) ret.genericToggle = bool(cp.vl["LIGHT_STALK"]["AUTO_HIGH_BEAM"])
ret.stockAeb = bool(cp_cam.vl["PRE_COLLISION"]["PRECOLLISION_ACTIVE"] and cp_cam.vl["PRE_COLLISION"]["FORCE"] < -1e-5) ret.stockAeb = bool(cp_cam.vl["PRE_COLLISION"]["PRECOLLISION_ACTIVE"] and cp_cam.vl["PRE_COLLISION"]["FORCE"] < -1e-5)
if self.CP.carFingerprint in TSS2_CAR:
ret.stockFcw = bool(cp_cam.vl["ACC_HUD"]["FCW"])
ret.espDisabled = cp.vl["ESP_CONTROL"]["TC_DISABLED"] != 0 ret.espDisabled = cp.vl["ESP_CONTROL"]["TC_DISABLED"] != 0
# 2 is standby, 10 is active. TODO: check that everything else is really a faulty state # 2 is standby, 10 is active. TODO: check that everything else is really a faulty state
self.steer_state = cp.vl["EPS_STATUS"]["LKA_STATE"] self.steer_state = cp.vl["EPS_STATUS"]["LKA_STATE"]
@ -220,7 +223,13 @@ class CarState(CarStateBase):
] ]
if CP.carFingerprint in TSS2_CAR: if CP.carFingerprint in TSS2_CAR:
signals.append(("ACC_TYPE", "ACC_CONTROL")) signals += [
checks.append(("ACC_CONTROL", 33)) ("ACC_TYPE", "ACC_CONTROL"),
("FCW", "ACC_HUD"),
]
checks += [
("ACC_CONTROL", 33),
("ACC_HUD", 1),
]
return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 2) return CANParser(DBC[CP.carFingerprint]["pt"], signals, checks, 2)

@ -1,6 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
from cereal import car from cereal import car
from common.conversions import Conversions as CV from common.conversions import Conversions as CV
from panda import Panda
from selfdrive.car.toyota.tunes import LatTunes, LongTunes, set_long_tune, set_lat_tune from selfdrive.car.toyota.tunes import LatTunes, LongTunes, set_long_tune, set_lat_tune
from selfdrive.car.toyota.values import Ecu, CAR, ToyotaFlags, TSS2_CAR, NO_DSU_CAR, MIN_ACC_SPEED, EPS_SCALE, EV_HYBRID_CAR, CarControllerParams from selfdrive.car.toyota.values import Ecu, CAR, ToyotaFlags, TSS2_CAR, NO_DSU_CAR, MIN_ACC_SPEED, EPS_SCALE, EV_HYBRID_CAR, CarControllerParams
from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config from selfdrive.car import STD_CARGO_KG, scale_rot_inertia, scale_tire_stiffness, gen_empty_fingerprint, get_safety_config
@ -22,6 +23,9 @@ class CarInterface(CarInterfaceBase):
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.toyota)] ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.toyota)]
ret.safetyConfigs[0].safetyParam = EPS_SCALE[candidate] ret.safetyConfigs[0].safetyParam = EPS_SCALE[candidate]
if candidate in (CAR.RAV4, CAR.PRIUS_V, CAR.COROLLA, CAR.LEXUS_ESH, CAR.LEXUS_CTH):
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_TOYOTA_ALT_BRAKE
ret.steerActuatorDelay = 0.12 # Default delay, Prius has larger delay ret.steerActuatorDelay = 0.12 # Default delay, Prius has larger delay
ret.steerLimitTimer = 0.4 ret.steerLimitTimer = 0.4
ret.stoppingControl = False # Toyota starts braking more when it thinks you want to stop ret.stoppingControl = False # Toyota starts braking more when it thinks you want to stop
@ -51,7 +55,7 @@ class CarInterface(CarInterfaceBase):
ret.steerRatio = 16.88 # 14.5 is spec end-to-end ret.steerRatio = 16.88 # 14.5 is spec end-to-end
tire_stiffness_factor = 0.5533 tire_stiffness_factor = 0.5533
ret.mass = 3650. * CV.LB_TO_KG + STD_CARGO_KG # mean between normal and hybrid ret.mass = 3650. * CV.LB_TO_KG + STD_CARGO_KG # mean between normal and hybrid
set_lat_tune(ret.lateralTuning, LatTunes.TORQUE, MAX_TORQUE=2.5, FRICTION=0.06) set_lat_tune(ret.lateralTuning, LatTunes.TORQUE, MAX_LAT_ACCEL=2.5, FRICTION=0.06)
elif candidate == CAR.COROLLA: elif candidate == CAR.COROLLA:
ret.wheelbase = 2.70 ret.wheelbase = 2.70
@ -132,7 +136,7 @@ class CarInterface(CarInterfaceBase):
ret.steerRatio = 13.9 ret.steerRatio = 13.9
tire_stiffness_factor = 0.444 # not optimized yet tire_stiffness_factor = 0.444 # not optimized yet
ret.mass = 3060. * CV.LB_TO_KG + STD_CARGO_KG ret.mass = 3060. * CV.LB_TO_KG + STD_CARGO_KG
set_lat_tune(ret.lateralTuning, LatTunes.TORQUE, MAX_TORQUE=3.0, FRICTION=0.08) set_lat_tune(ret.lateralTuning, LatTunes.TORQUE, MAX_LAT_ACCEL=3.0, FRICTION=0.08)
elif candidate in (CAR.LEXUS_ES_TSS2, CAR.LEXUS_ESH_TSS2, CAR.LEXUS_ESH): elif candidate in (CAR.LEXUS_ES_TSS2, CAR.LEXUS_ESH_TSS2, CAR.LEXUS_ESH):
stop_and_go = True stop_and_go = True

@ -50,13 +50,13 @@ def set_long_tune(tune, name):
###### LAT ###### ###### LAT ######
def set_lat_tune(tune, name, MAX_TORQUE=2.5, FRICTION=.1): def set_lat_tune(tune, name, MAX_LAT_ACCEL=2.5, FRICTION=.1):
if name == LatTunes.TORQUE: if name == LatTunes.TORQUE:
tune.init('torque') tune.init('torque')
tune.torque.useSteeringAngle = True tune.torque.useSteeringAngle = True
tune.torque.kp = 2.0 / MAX_TORQUE tune.torque.kp = 2.0 / MAX_LAT_ACCEL
tune.torque.kf = 1.0 / MAX_TORQUE tune.torque.kf = 1.0 / MAX_LAT_ACCEL
tune.torque.ki = 0.5 / MAX_TORQUE tune.torque.ki = 0.5 / MAX_LAT_ACCEL
tune.torque.friction = FRICTION tune.torque.friction = FRICTION
elif name == LatTunes.INDI_PRIUS: elif name == LatTunes.INDI_PRIUS:
tune.init('indi') tune.init('indi')

@ -266,6 +266,7 @@ FW_VERSIONS = {
}, },
CAR.AVALON_TSS2: { CAR.AVALON_TSS2: {
(Ecu.esp, 0x7b0, None): [ (Ecu.esp, 0x7b0, None): [
b'\x01F152607240\x00\x00\x00\x00\x00\x00',
b'\x01F152607280\x00\x00\x00\x00\x00\x00', b'\x01F152607280\x00\x00\x00\x00\x00\x00',
], ],
(Ecu.eps, 0x7a1, None): [ (Ecu.eps, 0x7a1, None): [
@ -276,9 +277,11 @@ FW_VERSIONS = {
], ],
(Ecu.fwdRadar, 0x750, 0xf): [ (Ecu.fwdRadar, 0x750, 0xf): [
b'\x018821F6201200\x00\x00\x00\x00', b'\x018821F6201200\x00\x00\x00\x00',
b'\x018821F6201300\x00\x00\x00\x00',
], ],
(Ecu.fwdCamera, 0x750, 0x6d): [ (Ecu.fwdCamera, 0x750, 0x6d): [
b'\x028646F4104100\x00\x00\x00\x008646G5301200\x00\x00\x00\x00', b'\x028646F4104100\x00\x00\x00\x008646G5301200\x00\x00\x00\x00',
b'\x028646F4104100\x00\x00\x00\x008646G3304000\x00\x00\x00\x00',
], ],
}, },
CAR.AVALONH_TSS2: { CAR.AVALONH_TSS2: {
@ -939,6 +942,7 @@ FW_VERSIONS = {
b'\x01F15264872500\x00\x00\x00\x00', b'\x01F15264872500\x00\x00\x00\x00',
b'\x01F15264873500\x00\x00\x00\x00', b'\x01F15264873500\x00\x00\x00\x00',
b'\x01F152648C6300\x00\x00\x00\x00', b'\x01F152648C6300\x00\x00\x00\x00',
b'\x01F152648J4000\x00\x00\x00\x00',
], ],
(Ecu.engine, 0x700, None): [ (Ecu.engine, 0x700, None): [
b'\x01896630E67000\x00\x00\x00\x00', b'\x01896630E67000\x00\x00\x00\x00',
@ -1680,6 +1684,7 @@ FW_VERSIONS = {
b'\x018966348W9000\x00\x00\x00\x00', b'\x018966348W9000\x00\x00\x00\x00',
b'\x01896634D12000\x00\x00\x00\x00', b'\x01896634D12000\x00\x00\x00\x00',
b'\x01896634D12100\x00\x00\x00\x00', b'\x01896634D12100\x00\x00\x00\x00',
b'\x01896634D43000\x00\x00\x00\x00',
], ],
(Ecu.esp, 0x7b0, None): [ (Ecu.esp, 0x7b0, None): [
b'\x01F15260E031\x00\x00\x00\x00\x00\x00', b'\x01F15260E031\x00\x00\x00\x00\x00\x00',
@ -1700,6 +1705,7 @@ FW_VERSIONS = {
b'\x028646F4810100\x00\x00\x00\x008646G2601200\x00\x00\x00\x00', b'\x028646F4810100\x00\x00\x00\x008646G2601200\x00\x00\x00\x00',
b'\x028646F4810200\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', b'\x028646F4810200\x00\x00\x00\x008646G2601400\x00\x00\x00\x00',
b'\x028646F4810300\x00\x00\x00\x008646G2601400\x00\x00\x00\x00', b'\x028646F4810300\x00\x00\x00\x008646G2601400\x00\x00\x00\x00',
b'\x028646F4810400\x00\x00\x00\x008646G2601400\x00\x00\x00\x00',
], ],
}, },
CAR.LEXUS_RXH_TSS2: { CAR.LEXUS_RXH_TSS2: {

@ -75,11 +75,6 @@ class CarState(CarStateBase):
# Update seatbelt fastened status. # Update seatbelt fastened status.
ret.seatbeltUnlatched = pt_cp.vl["Airbag_02"]["AB_Gurtschloss_FA"] != 3 ret.seatbeltUnlatched = pt_cp.vl["Airbag_02"]["AB_Gurtschloss_FA"] != 3
# Update driver preference for metric. VW stores many different unit
# preferences, including separate units for for distance vs. speed.
# We use the speed preference for OP.
self.displayMetricUnits = not pt_cp.vl["Einheiten_01"]["KBI_MFA_v_Einheit_02"]
# Consume blind-spot monitoring info/warning LED states, if available. # Consume blind-spot monitoring info/warning LED states, if available.
# Infostufe: BSM LED on, Warnung: BSM LED flashing # Infostufe: BSM LED on, Warnung: BSM LED flashing
if self.CP.enableBsm: if self.CP.enableBsm:
@ -182,7 +177,6 @@ class CarState(CarStateBase):
("EPS_HCA_Status", "LH_EPS_03"), # EPS HCA control status ("EPS_HCA_Status", "LH_EPS_03"), # EPS HCA control status
("ESP_Tastung_passiv", "ESP_21"), # Stability control disabled ("ESP_Tastung_passiv", "ESP_21"), # Stability control disabled
("ESP_Haltebestaetigung", "ESP_21"), # ESP hold confirmation ("ESP_Haltebestaetigung", "ESP_21"), # ESP hold confirmation
("KBI_MFA_v_Einheit_02", "Einheiten_01"), # MPH vs KMH speed display
("KBI_Handbremse", "Kombi_01"), # Manual handbrake applied ("KBI_Handbremse", "Kombi_01"), # Manual handbrake applied
("KBI_Variante", "Kombi_03"), # Digital/full-screen instrument cluster installed ("KBI_Variante", "Kombi_03"), # Digital/full-screen instrument cluster installed
("TSK_Status", "TSK_06"), # ACC engagement status from drivetrain coordinator ("TSK_Status", "TSK_06"), # ACC engagement status from drivetrain coordinator
@ -214,7 +208,6 @@ class CarState(CarStateBase):
("Airbag_02", 5), # From J234 Airbag control module ("Airbag_02", 5), # From J234 Airbag control module
("Kombi_01", 2), # From J285 Instrument cluster ("Kombi_01", 2), # From J285 Instrument cluster
("Blinkmodi_02", 1), # From J519 BCM (sent at 1Hz when no lights active, 50Hz when active) ("Blinkmodi_02", 1), # From J519 BCM (sent at 1Hz when no lights active, 50Hz when active)
("Einheiten_01", 1), # From J??? not known if gateway, cluster, or BCM
("Kombi_03", 1), # From J285 instrument cluster ("Kombi_03", 1), # From J285 instrument cluster
] ]

@ -13,7 +13,6 @@ class CarInterface(CarInterfaceBase):
def __init__(self, CP, CarController, CarState): def __init__(self, CP, CarController, CarState):
super().__init__(CP, CarController, CarState) super().__init__(CP, CarController, CarState)
self.displayMetricUnitsPrev = None
self.buttonStatesPrev = BUTTON_STATES.copy() self.buttonStatesPrev = BUTTON_STATES.copy()
if CP.networkLocation == NetworkLocation.fwdCamera: if CP.networkLocation == NetworkLocation.fwdCamera:
@ -227,7 +226,6 @@ class CarInterface(CarInterfaceBase):
ret.buttonEvents = buttonEvents ret.buttonEvents = buttonEvents
# update previous car states # update previous car states
self.displayMetricUnitsPrev = self.CS.displayMetricUnits
self.buttonStatesPrev = self.CS.buttonStates.copy() self.buttonStatesPrev = self.CS.buttonStates.copy()
return ret return ret

@ -148,6 +148,7 @@ CAR_INFO: Dict[str, Union[VWCarInfo, List[VWCarInfo]]] = {
CAR.AUDI_A3_MK3: [ CAR.AUDI_A3_MK3: [
VWCarInfo("Audi A3 2014-19", "ACC + Lane Assist"), VWCarInfo("Audi A3 2014-19", "ACC + Lane Assist"),
VWCarInfo("Audi A3 Sportback e-tron 2017-18", "ACC + Lane Assist"), VWCarInfo("Audi A3 Sportback e-tron 2017-18", "ACC + Lane Assist"),
VWCarInfo("Audi RS3 2018", "ACC + Lane Assist"),
VWCarInfo("Audi S3 2015-17", "ACC + Lane Assist"), VWCarInfo("Audi S3 2015-17", "ACC + Lane Assist"),
], ],
CAR.AUDI_Q2_MK1: VWCarInfo("Audi Q2 2018", "ACC + Lane Assist"), CAR.AUDI_Q2_MK1: VWCarInfo("Audi Q2 2018", "ACC + Lane Assist"),
@ -622,6 +623,7 @@ FW_VERSIONS = {
b'\xf1\x878V0906259K \xf1\x890001', b'\xf1\x878V0906259K \xf1\x890001',
b'\xf1\x878V0906264B \xf1\x890003', b'\xf1\x878V0906264B \xf1\x890003',
b'\xf1\x878V0907115B \xf1\x890007', b'\xf1\x878V0907115B \xf1\x890007',
b'\xf1\x878V0907404A \xf1\x890005',
], ],
(Ecu.transmission, 0x7e1, None): [ (Ecu.transmission, 0x7e1, None): [
b'\xf1\x870CW300044T \xf1\x895245', b'\xf1\x870CW300044T \xf1\x895245',
@ -633,12 +635,14 @@ FW_VERSIONS = {
b'\xf1\x870DD300046A \xf1\x891602', b'\xf1\x870DD300046A \xf1\x891602',
b'\xf1\x870DD300046F \xf1\x891602', b'\xf1\x870DD300046F \xf1\x891602',
b'\xf1\x870DD300046G \xf1\x891601', b'\xf1\x870DD300046G \xf1\x891601',
b'\xf1\x870DL300012E \xf1\x892012',
b'\xf1\x870GC300013M \xf1\x892402', b'\xf1\x870GC300013M \xf1\x892402',
b'\xf1\x870GC300042J \xf1\x891402', b'\xf1\x870GC300042J \xf1\x891402',
], ],
(Ecu.srs, 0x715, None): [ (Ecu.srs, 0x715, None): [
b'\xf1\x875Q0959655AB\xf1\x890388\xf1\x82\0211111001111111206110412111321139114', b'\xf1\x875Q0959655AB\xf1\x890388\xf1\x82\0211111001111111206110412111321139114',
b'\xf1\x875Q0959655AM\xf1\x890315\xf1\x82\x1311111111111111311411011231129321212100', b'\xf1\x875Q0959655AM\xf1\x890315\xf1\x82\x1311111111111111311411011231129321212100',
b'\xf1\x875Q0959655BJ\xf1\x890339\xf1\x82\x1311110011131100311111011731179321342100',
b'\xf1\x875Q0959655J \xf1\x890825\xf1\x82\023111112111111--171115141112221291163221', b'\xf1\x875Q0959655J \xf1\x890825\xf1\x82\023111112111111--171115141112221291163221',
b'\xf1\x875Q0959655J \xf1\x890830\xf1\x82\023121111111211--261117141112231291163221', b'\xf1\x875Q0959655J \xf1\x890830\xf1\x82\023121111111211--261117141112231291163221',
b'\xf1\x875Q0959655J \xf1\x890830\xf1\x82\x13121111111111--341117141212231291163221', b'\xf1\x875Q0959655J \xf1\x890830\xf1\x82\x13121111111111--341117141212231291163221',
@ -648,6 +652,7 @@ FW_VERSIONS = {
(Ecu.eps, 0x712, None): [ (Ecu.eps, 0x712, None): [
b'\xf1\x873Q0909144H \xf1\x895061\xf1\x82\00566G0HA14A1', b'\xf1\x873Q0909144H \xf1\x895061\xf1\x82\00566G0HA14A1',
b'\xf1\x873Q0909144K \xf1\x895072\xf1\x82\x0571G0HA16A1', b'\xf1\x873Q0909144K \xf1\x895072\xf1\x82\x0571G0HA16A1',
b'\xf1\x873Q0909144L \xf1\x895081\xf1\x82\x0571G0JA14A1',
b'\xf1\x875Q0909144AB\xf1\x891082\xf1\x82\00521G0G809A1', b'\xf1\x875Q0909144AB\xf1\x891082\xf1\x82\00521G0G809A1',
b'\xf1\x875Q0909144P \xf1\x891043\xf1\x82\00503G00303A0', b'\xf1\x875Q0909144P \xf1\x891043\xf1\x82\00503G00303A0',
b'\xf1\x875Q0909144P \xf1\x891043\xf1\x82\00503G00803A0', b'\xf1\x875Q0909144P \xf1\x891043\xf1\x82\00503G00803A0',

@ -134,7 +134,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"LastPeripheralPandaType", PERSISTENT}, {"LastPeripheralPandaType", PERSISTENT},
{"LastPowerDropDetected", CLEAR_ON_MANAGER_START}, {"LastPowerDropDetected", CLEAR_ON_MANAGER_START},
{"LastSystemShutdown", CLEAR_ON_MANAGER_START}, {"LastSystemShutdown", CLEAR_ON_MANAGER_START},
{"LastUpdateException", PERSISTENT}, {"LastUpdateException", CLEAR_ON_MANAGER_START},
{"LastUpdateTime", PERSISTENT}, {"LastUpdateTime", PERSISTENT},
{"LiveParameters", PERSISTENT}, {"LiveParameters", PERSISTENT},
{"NavDestination", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF}, {"NavDestination", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF},

@ -538,7 +538,7 @@ class Controls:
# Check which actuators can be enabled # Check which actuators can be enabled
CC.latActive = self.active and not CS.steerFaultTemporary and not CS.steerFaultPermanent and \ CC.latActive = self.active and not CS.steerFaultTemporary and not CS.steerFaultPermanent and \
CS.vEgo > self.CP.minSteerSpeed and not CS.standstill CS.vEgo > self.CP.minSteerSpeed and not CS.standstill
CC.longActive = self.active and not self.events.any(ET.OVERRIDE) CC.longActive = self.active and not self.events.any(ET.OVERRIDE) and self.CP.openpilotLongitudinalControl
actuators = CC.actuators actuators = CC.actuators
actuators.longControlState = self.LoC.long_control_state actuators.longControlState = self.LoC.long_control_state

@ -251,6 +251,32 @@ def no_gps_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_
AlertStatus.normal, AlertSize.mid, AlertStatus.normal, AlertSize.mid,
Priority.LOWER, VisualAlert.none, AudibleAlert.none, .2, creation_delay=300.) Priority.LOWER, VisualAlert.none, AudibleAlert.none, .2, creation_delay=300.)
# *** debug alerts ***
def out_of_space_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert:
full_perc = round(100. - sm['deviceState'].freeSpacePercent)
return NormalPermanentAlert("Out of Storage", f"{full_perc}% full")
def overheat_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert:
cpu = max(sm['deviceState'].cpuTempC, default=0.)
gpu = max(sm['deviceState'].gpuTempC, default=0.)
temp = max((cpu, gpu, sm['deviceState'].memoryTempC))
return NormalPermanentAlert("System Overheated", f"{temp} °C")
def low_memory_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert:
return NormalPermanentAlert("Low Memory", f"{sm['deviceState'].memoryUsagePercent}% used")
def high_cpu_usage_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert:
x = max(sm['deviceState'].cpuUsagePercent, default=0.)
return NormalPermanentAlert("High CPU Usage", f"{x}% used")
def modeld_lagging_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert:
return NormalPermanentAlert("Driving model lagging", f"{sm['modelV2'].frameDropPerc}% frames dropped")
def wrong_car_mode_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert: def wrong_car_mode_alert(CP: car.CarParams, sm: messaging.SubMaster, metric: bool, soft_disable_time: int) -> Alert:
text = "Cruise Mode Disabled" text = "Cruise Mode Disabled"
@ -578,7 +604,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = {
}, },
EventName.outOfSpace: { EventName.outOfSpace: {
ET.PERMANENT: NormalPermanentAlert("Out of Storage"), ET.PERMANENT: out_of_space_alert,
ET.NO_ENTRY: NoEntryAlert("Out of Storage"), ET.NO_ENTRY: NoEntryAlert("Out of Storage"),
}, },
@ -609,7 +635,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = {
}, },
EventName.overheat: { EventName.overheat: {
ET.PERMANENT: NormalPermanentAlert("System Overheated"), ET.PERMANENT: overheat_alert,
ET.SOFT_DISABLE: soft_disable_alert("System Overheated"), ET.SOFT_DISABLE: soft_disable_alert("System Overheated"),
ET.NO_ENTRY: NoEntryAlert("System Overheated"), ET.NO_ENTRY: NoEntryAlert("System Overheated"),
}, },
@ -685,6 +711,7 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = {
EventName.modeldLagging: { EventName.modeldLagging: {
ET.SOFT_DISABLE: soft_disable_alert("Driving model lagging"), ET.SOFT_DISABLE: soft_disable_alert("Driving model lagging"),
ET.NO_ENTRY: NoEntryAlert("Driving model lagging"), ET.NO_ENTRY: NoEntryAlert("Driving model lagging"),
ET.PERMANENT: modeld_lagging_alert,
}, },
# Besides predicting the path, lane lines and lead car data the model also # Besides predicting the path, lane lines and lead car data the model also
@ -706,14 +733,14 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = {
EventName.lowMemory: { EventName.lowMemory: {
ET.SOFT_DISABLE: soft_disable_alert("Low Memory: Reboot Your Device"), ET.SOFT_DISABLE: soft_disable_alert("Low Memory: Reboot Your Device"),
ET.PERMANENT: NormalPermanentAlert("Low Memory", "Reboot your Device"), ET.PERMANENT: low_memory_alert,
ET.NO_ENTRY: NoEntryAlert("Low Memory: Reboot Your Device"), ET.NO_ENTRY: NoEntryAlert("Low Memory: Reboot Your Device"),
}, },
EventName.highCpuUsage: { EventName.highCpuUsage: {
#ET.SOFT_DISABLE: soft_disable_alert("System Malfunction: Reboot Your Device"), #ET.SOFT_DISABLE: soft_disable_alert("System Malfunction: Reboot Your Device"),
#ET.PERMANENT: NormalPermanentAlert("System Malfunction", "Reboot your Device"), #ET.PERMANENT: NormalPermanentAlert("System Malfunction", "Reboot your Device"),
ET.NO_ENTRY: NoEntryAlert("System Malfunction: Reboot Your Device"), ET.NO_ENTRY: high_cpu_usage_alert,
}, },
EventName.accFaulted: { EventName.accFaulted: {

@ -59,14 +59,14 @@ class LatControlTorque(LatControl):
pid_log.error = error pid_log.error = error
ff = desired_lateral_accel - params.roll * ACCELERATION_DUE_TO_GRAVITY ff = desired_lateral_accel - params.roll * ACCELERATION_DUE_TO_GRAVITY
# convert friction into lateral accel units for feedforward
friction_compensation = interp(desired_lateral_jerk, [-JERK_THRESHOLD, JERK_THRESHOLD], [-self.friction, self.friction])
ff += friction_compensation / CP.lateralTuning.torque.kf
output_torque = self.pid.update(error, output_torque = self.pid.update(error,
override=CS.steeringPressed, feedforward=ff, override=CS.steeringPressed, feedforward=ff,
speed=CS.vEgo, speed=CS.vEgo,
freeze_integrator=CS.steeringRateLimited) freeze_integrator=CS.steeringRateLimited)
friction_compensation = interp(desired_lateral_jerk, [-JERK_THRESHOLD, JERK_THRESHOLD], [-self.friction, self.friction])
output_torque += friction_compensation
pid_log.active = True pid_log.active = True
pid_log.p = self.pid.p pid_log.p = self.pid.p
pid_log.i = self.pid.i pid_log.i = self.pid.i

@ -345,6 +345,11 @@ class LongitudinalMpc:
self.crash_cnt = 0 self.crash_cnt = 0
def update_with_xva(self, x, v, a): def update_with_xva(self, x, v, a):
# v, and a are in local frame, but x is wrt the x[0] position
# In >90degree turns, x goes to 0 (and may even be -ve)
# So, we use integral(v) + x[0] to obtain the forward-distance
xforward = ((v[1:] + v[:-1]) / 2) * (T_IDXS[1:] - T_IDXS[:-1])
x = np.cumsum(np.insert(xforward, 0, x[0]))
self.yref[:,1] = x self.yref[:,1] = x
self.yref[:,2] = v self.yref[:,2] = v
self.yref[:,3] = a self.yref[:,3] = a

@ -1,15 +1,11 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# flake8: noqa
# pylint: skip-file
# type: ignore
import time import time
from cereal import car, log from cereal import car, log
import cereal.messaging as messaging import cereal.messaging as messaging
from common.realtime import DT_CTRL from common.realtime import DT_CTRL
from selfdrive.car.honda.interface import CarInterface from selfdrive.car.honda.interface import CarInterface
from selfdrive.controls.lib.events import ET, EVENTS, Events from selfdrive.controls.lib.events import ET, Events
from selfdrive.controls.lib.alertmanager import AlertManager from selfdrive.controls.lib.alertmanager import AlertManager
EventName = car.CarEvent.EventName EventName = car.CarEvent.EventName
@ -33,10 +29,26 @@ def cycle_alerts(duration=200, is_metric=False):
(EventName.driverDistracted, ET.WARNING), (EventName.driverDistracted, ET.WARNING),
] ]
# debug alerts
alerts = [
(EventName.highCpuUsage, ET.NO_ENTRY),
(EventName.lowMemory, ET.PERMANENT),
(EventName.overheat, ET.PERMANENT),
(EventName.outOfSpace, ET.PERMANENT),
(EventName.modeldLagging, ET.PERMANENT),
]
CP = CarInterface.get_params("HONDA CIVIC 2016") CP = CarInterface.get_params("HONDA CIVIC 2016")
sm = messaging.SubMaster(['deviceState', 'pandaStates', 'roadCameraState', 'modelV2', 'liveCalibration', sm = messaging.SubMaster(['deviceState', 'pandaStates', 'roadCameraState', 'modelV2', 'liveCalibration',
'driverMonitoringState', 'longitudinalPlan', 'lateralPlan', 'liveLocationKalman']) 'driverMonitoringState', 'longitudinalPlan', 'lateralPlan', 'liveLocationKalman'])
sm['deviceState'].freeSpacePercent = 55
sm['deviceState'].memoryUsagePercent = 55
sm['deviceState'].cpuTempC = [1, 2, 100]
sm['deviceState'].gpuTempC = [211, 2, 100]
sm['deviceState'].cpuUsagePercent = [23, 54]
sm['modelV2'].frameDropPerc = 20
pm = messaging.PubMaster(['controlsState', 'pandaStates', 'deviceState']) pm = messaging.PubMaster(['controlsState', 'pandaStates', 'deviceState'])
events = Events() events = Events()
@ -44,30 +56,27 @@ def cycle_alerts(duration=200, is_metric=False):
frame = 0 frame = 0
while True: while True:
current_alert_types = [ET.PERMANENT, ET.USER_DISABLE, ET.IMMEDIATE_DISABLE,
ET.SOFT_DISABLE, ET.PRE_ENABLE, ET.NO_ENTRY,
ET.ENABLE, ET.WARNING]
for alert, et in alerts: for alert, et in alerts:
events.clear() events.clear()
events.add(alert) events.add(alert)
a = events.create_alerts([et, ], [CP, sm, is_metric, 0]) a = events.create_alerts([et, ], [CP, sm, is_metric, 0])
AM.add_many(frame, a) AM.add_many(frame, a)
AM.process_alerts(frame) alert = AM.process_alerts(frame, [])
print(AM.alert) print(alert)
for _ in range(duration): for _ in range(duration):
dat = messaging.new_message() dat = messaging.new_message()
dat.init('controlsState') dat.init('controlsState')
dat.controlsState.enabled = True dat.controlsState.enabled = False
dat.controlsState.alertText1 = AM.alert_text_1 if alert:
dat.controlsState.alertText2 = AM.alert_text_2 dat.controlsState.alertText1 = alert.alert_text_1
dat.controlsState.alertSize = AM.alert_size dat.controlsState.alertText2 = alert.alert_text_2
dat.controlsState.alertStatus = AM.alert_status dat.controlsState.alertSize = alert.alert_size
dat.controlsState.alertBlinkingRate = AM.alert_rate dat.controlsState.alertStatus = alert.alert_status
dat.controlsState.alertType = AM.alert_type dat.controlsState.alertBlinkingRate = alert.alert_rate
dat.controlsState.alertSound = AM.audible_alert dat.controlsState.alertType = alert.alert_type
dat.controlsState.alertSound = alert.audible_alert
pm.send('controlsState', dat) pm.send('controlsState', dat)
dat = messaging.new_message() dat = messaging.new_message()

@ -74,7 +74,7 @@ if __name__ == "__main__":
print("\nyou didn't type 'OK! (aborted)") print("\nyou didn't type 'OK! (aborted)")
sys.exit(0) sys.exit(0)
panda = Panda() # type: ignore panda = Panda()
panda.set_safety_mode(Panda.SAFETY_ELM327) panda.set_safety_mode(Panda.SAFETY_ELM327)
uds_client = UdsClient(panda, 0x7D0, bus=args.bus, debug=args.debug) uds_client = UdsClient(panda, 0x7D0, bus=args.bus, debug=args.debug)

@ -1,11 +1,12 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import cereal.messaging as messaging import cereal.messaging as messaging
from typing import Optional
if __name__ == "__main__": if __name__ == "__main__":
modeld_sock = messaging.sub_sock("modelV2") modeld_sock = messaging.sub_sock("modelV2")
last_frame_id = None last_frame_id = None
start_t = None start_t: Optional[int] = None
frame_cnt = 0 frame_cnt = 0
dropped = 0 dropped = 0

@ -1,9 +1,10 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import argparse import argparse
import capnp
from cereal.messaging import SubMaster from cereal.messaging import SubMaster
from common.numpy_fast import mean from common.numpy_fast import mean
from typing import Optional
def cputime_total(ct): def cputime_total(ct):
return ct.user + ct.nice + ct.system + ct.idle + ct.iowait + ct.irq + ct.softirq return ct.user + ct.nice + ct.system + ct.idle + ct.iowait + ct.irq + ct.softirq
@ -40,8 +41,8 @@ if __name__ == "__main__":
total_times = [0.]*8 total_times = [0.]*8
busy_times = [0.]*8 busy_times = [0.]*8
prev_proclog = None prev_proclog: Optional[capnp._DynamicStructReader] = None
prev_proclog_t = None prev_proclog_t: Optional[int] = None
while True: while True:
sm.update() sm.update()
@ -73,7 +74,7 @@ if __name__ == "__main__":
print(f"CPU {100.0 * mean(cores):.2f}% - RAM: {last_mem:.2f}% - Temp {last_temp:.2f}C") print(f"CPU {100.0 * mean(cores):.2f}% - RAM: {last_mem:.2f}% - Temp {last_temp:.2f}C")
if args.cpu and prev_proclog is not None: if args.cpu and prev_proclog is not None and prev_proclog_t is not None:
procs = {} procs = {}
dt = (sm.logMonoTime['procLog'] - prev_proclog_t) / 1e9 dt = (sm.logMonoTime['procLog'] - prev_proclog_t) / 1e9
for proc in m.procs: for proc in m.procs:

@ -44,7 +44,7 @@ class HardwareBase(ABC):
pass pass
@abstractmethod @abstractmethod
def get_imei(self, slot): def get_imei(self, slot) -> str:
pass pass
@abstractmethod @abstractmethod
@ -158,3 +158,9 @@ class HardwareBase(ABC):
@abstractmethod @abstractmethod
def get_networks(self): def get_networks(self):
pass pass
def reset_internal_panda(self):
pass
def recover_internal_panda(self):
pass

@ -16,7 +16,7 @@ class StreamingDecompressor:
def __init__(self, url: str) -> None: def __init__(self, url: str) -> None:
self.buf = b"" self.buf = b""
self.req = requests.get(url, stream=True, headers={'Accept-Encoding': None}) self.req = requests.get(url, stream=True, headers={'Accept-Encoding': None}) # type: ignore
self.it = self.req.iter_content(chunk_size=1024 * 1024) self.it = self.req.iter_content(chunk_size=1024 * 1024)
self.decompressor = lzma.LZMADecompressor(format=lzma.FORMAT_AUTO) self.decompressor = lzma.LZMADecompressor(format=lzma.FORMAT_AUTO)
self.eof = False self.eof = False

@ -2,13 +2,16 @@ import json
import math import math
import os import os
import subprocess import subprocess
import time
from enum import IntEnum from enum import IntEnum
from functools import cached_property from functools import cached_property
from pathlib import Path from pathlib import Path
from cereal import log from cereal import log
from common.gpio import gpio_set, gpio_init
from selfdrive.hardware.base import HardwareBase, ThermalConfig from selfdrive.hardware.base import HardwareBase, ThermalConfig
from selfdrive.hardware.tici import iwlist from selfdrive.hardware.tici import iwlist
from selfdrive.hardware.tici.pins import GPIO
from selfdrive.hardware.tici.amplifier import Amplifier from selfdrive.hardware.tici.amplifier import Amplifier
NM = 'org.freedesktop.NetworkManager' NM = 'org.freedesktop.NetworkManager'
@ -415,12 +418,12 @@ class Tici(HardwareBase):
# offline big cluster, leave core 4 online for boardd # offline big cluster, leave core 4 online for boardd
for i in range(5, 8): for i in range(5, 8):
val = "0" if powersave_enabled else "1" val = '0' if powersave_enabled else '1'
sudo_write(val, f"/sys/devices/system/cpu/cpu{i}/online") sudo_write(val, f'/sys/devices/system/cpu/cpu{i}/online')
for n in ('0', '4'): for n in ('0', '4'):
gov = 'ondemand' if powersave_enabled else 'performance' gov = 'ondemand' if powersave_enabled else 'performance'
sudo_write(gov, f"/sys/devices/system/cpu/cpufreq/policy{n}/scaling_governor") sudo_write(gov, f'/sys/devices/system/cpu/cpufreq/policy{n}/scaling_governor')
# *** IRQ config *** # *** IRQ config ***
affine_irq(5, 565) # kgsl-3d0 affine_irq(5, 565) # kgsl-3d0
@ -450,13 +453,15 @@ class Tici(HardwareBase):
sudo_write("f", "/proc/irq/default_smp_affinity") sudo_write("f", "/proc/irq/default_smp_affinity")
# *** GPU config *** # *** GPU config ***
sudo_write("0", "/sys/class/kgsl/kgsl-3d0/min_pwrlevel") # https://github.com/commaai/agnos-kernel-sdm845/blob/master/arch/arm64/boot/dts/qcom/sdm845-gpu.dtsi#L216
sudo_write("0", "/sys/class/kgsl/kgsl-3d0/max_pwrlevel") sudo_write("1", "/sys/class/kgsl/kgsl-3d0/min_pwrlevel")
sudo_write("1", "/sys/class/kgsl/kgsl-3d0/max_pwrlevel")
sudo_write("1", "/sys/class/kgsl/kgsl-3d0/force_bus_on") sudo_write("1", "/sys/class/kgsl/kgsl-3d0/force_bus_on")
sudo_write("1", "/sys/class/kgsl/kgsl-3d0/force_clk_on") sudo_write("1", "/sys/class/kgsl/kgsl-3d0/force_clk_on")
sudo_write("1", "/sys/class/kgsl/kgsl-3d0/force_rail_on") sudo_write("1", "/sys/class/kgsl/kgsl-3d0/force_rail_on")
sudo_write("1000000", "/sys/class/kgsl/kgsl-3d0/idle_timer") sudo_write("1000000", "/sys/class/kgsl/kgsl-3d0/idle_timer")
sudo_write("performance", "/sys/class/kgsl/kgsl-3d0/devfreq/governor") sudo_write("performance", "/sys/class/kgsl/kgsl-3d0/devfreq/governor")
sudo_write("596", "/sys/class/kgsl/kgsl-3d0/max_clock_mhz")
# setup governors # setup governors
sudo_write("performance", "/sys/class/devfreq/soc:qcom,cpubw/governor") sudo_write("performance", "/sys/class/devfreq/soc:qcom,cpubw/governor")
@ -509,6 +514,24 @@ class Tici(HardwareBase):
return r return r
def reset_internal_panda(self):
gpio_init(GPIO.STM_RST_N, True)
gpio_set(GPIO.STM_RST_N, 1)
time.sleep(2)
gpio_set(GPIO.STM_RST_N, 0)
def recover_internal_panda(self):
gpio_init(GPIO.STM_RST_N, True)
gpio_init(GPIO.STM_BOOT0, True)
gpio_set(GPIO.STM_RST_N, 1)
gpio_set(GPIO.STM_BOOT0, 1)
time.sleep(2)
gpio_set(GPIO.STM_RST_N, 0)
gpio_set(GPIO.STM_BOOT0, 0)
if __name__ == "__main__": if __name__ == "__main__":
t = Tici() t = Tici()

@ -1,4 +1,5 @@
# TODO: these are also defined in a header # TODO: these are also defined in a header
# GPIO pin definitions # GPIO pin definitions
class GPIO: class GPIO:
# both GPIO_STM_RST_N and GPIO_LTE_RST_N are misnamed, they are high to reset # both GPIO_STM_RST_N and GPIO_LTE_RST_N are misnamed, they are high to reset
@ -18,5 +19,3 @@ class GPIO:
CAM0_RSTN = 9 CAM0_RSTN = 9
CAM1_RSTN = 7 CAM1_RSTN = 7
CAM2_RSTN = 12 CAM2_RSTN = 12

@ -1,11 +1,32 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import sys import sys
import time import time
import numpy as np
from typing import List
from common.realtime import Ratekeeper
def average(avg, sample): def average(avg, sample):
# Weighted avg between existing value and new sample # Weighted avg between existing value and new sample
return ((avg[0] * avg[1] + sample) / (avg[1] + 1), avg[1] + 1) return ((avg[0] * avg[1] + sample) / (avg[1] + 1), avg[1] + 1)
def sample_power(seconds=5) -> List[float]:
rate = 123
rk = Ratekeeper(rate, print_delay_threshold=None)
pwrs = []
for _ in range(rate*seconds):
with open("/sys/bus/i2c/devices/0-0040/hwmon/hwmon1/power1_input") as f:
pwrs.append(int(f.read()) / 1e6)
rk.keep_time()
return pwrs
def get_power(seconds=5):
pwrs = sample_power(seconds)
return np.mean(pwrs)
if __name__ == '__main__': if __name__ == '__main__':
sample_time = None sample_time = None
@ -17,7 +38,6 @@ if __name__ == '__main__':
voltage_average = (0, 0) # average, count voltage_average = (0, 0) # average, count
current_average = (0, 0) current_average = (0, 0)
power_average = (0, 0) power_average = (0, 0)
power_total_average = (0, 0)
while sample_time is None or time.monotonic() - start_time < sample_time: while sample_time is None or time.monotonic() - start_time < sample_time:
with open("/sys/bus/i2c/devices/0-0040/hwmon/hwmon1/in1_input") as f: with open("/sys/bus/i2c/devices/0-0040/hwmon/hwmon1/in1_input") as f:
voltage_total = int(f.read()) / 1000. voltage_total = int(f.read()) / 1000.
@ -25,23 +45,23 @@ if __name__ == '__main__':
with open("/sys/bus/i2c/devices/0-0040/hwmon/hwmon1/curr1_input") as f: with open("/sys/bus/i2c/devices/0-0040/hwmon/hwmon1/curr1_input") as f:
current_total = int(f.read()) current_total = int(f.read())
with open("/sys/class/power_supply/bms/voltage_now") as f: # SOM measurements are questionable
voltage = int(f.read()) / 1e6 # volts #with open("/sys/class/power_supply/bms/voltage_now") as f:
# voltage = int(f.read()) / 1e6 # volts
with open("/sys/class/power_supply/bms/current_now") as f: #with open("/sys/class/power_supply/bms/current_now") as f:
current = int(f.read()) / 1e3 # ma # current = int(f.read()) / 1e3 # ma
power = voltage*current
power_total = voltage_total*current_total power_total = voltage_total*current_total
# compute averages # compute averages
voltage_average = average(voltage_average, voltage) voltage_average = average(voltage_average, voltage_total)
current_average = average(current_average, current) current_average = average(current_average, current_total)
power_average = average(power_average, power) power_average = average(power_average, power_total)
power_total_average = average(power_total_average, power_total)
print(f"{power:12.2f} mW {power_total:12.2f} mW {power_total - power:12.2f} mW") print(f"now: {power_total:.2f} mW, avg: {power_average[0]:.2f} mW")
time.sleep(0.25) time.sleep(0.25)
except KeyboardInterrupt:
pass
finally: finally:
stop_time = time.monotonic() stop_time = time.monotonic()
print("\n----------------------Average-----------------------------------") print("\n----------------------Average-----------------------------------")

@ -0,0 +1,9 @@
#!/usr/bin/env python3
import numpy as np
from selfdrive.hardware.tici.power_monitor import sample_power
if __name__ == '__main__':
print("measuring for 5 seconds")
for _ in range(3):
pwrs = sample_power()
print("mean %.2f std %.2f" % (np.mean(pwrs), np.std(pwrs)))

@ -0,0 +1,61 @@
#!/usr/bin/env python3
import unittest
import time
import math
from collections import OrderedDict
from selfdrive.hardware import HARDWARE, TICI
from selfdrive.hardware.tici.power_monitor import get_power
from selfdrive.manager.process_config import managed_processes
from selfdrive.manager.manager import manager_cleanup
POWER = OrderedDict(
camerad=2.58,
modeld=0.90,
dmonitoringmodeld=0.25,
loggerd=0.45,
)
class TestPowerDraw(unittest.TestCase):
@classmethod
def setUpClass(cls):
if not TICI:
raise unittest.SkipTest
def setUp(self):
HARDWARE.initialize_hardware()
HARDWARE.set_power_save(False)
def tearDown(self):
manager_cleanup()
def test_camera_procs(self):
baseline = get_power()
prev = baseline
used = {}
for proc in POWER.keys():
managed_processes[proc].start()
time.sleep(6)
now = get_power(8)
used[proc] = now - prev
prev = now
manager_cleanup()
print("-"*35)
print(f"Baseline {baseline:.2f}W\n")
for proc in POWER.keys():
cur = used[proc]
expected = POWER[proc]
print(f"{proc.ljust(20)} {expected:.2f}W {cur:.2f}W")
with self.subTest(proc=proc):
self.assertTrue(math.isclose(cur, expected, rel_tol=0.10, abs_tol=0.1))
print("-"*35)
if __name__ == "__main__":
unittest.main()

@ -1,14 +1,12 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import gc
import math import math
import json import json
import numpy as np import numpy as np
import cereal.messaging as messaging import cereal.messaging as messaging
from cereal import car from cereal import car
from common.params import Params, put_nonblocking from common.params import Params, put_nonblocking
from common.realtime import set_realtime_priority, DT_MDL from common.realtime import config_realtime_process, DT_MDL
from common.numpy_fast import clip from common.numpy_fast import clip
from selfdrive.locationd.models.car_kf import CarKalman, ObservationKind, States from selfdrive.locationd.models.car_kf import CarKalman, ObservationKind, States
from selfdrive.locationd.models.constants import GENERATED_DIR from selfdrive.locationd.models.constants import GENERATED_DIR
@ -103,8 +101,7 @@ class ParamsLearner:
def main(sm=None, pm=None): def main(sm=None, pm=None):
gc.disable() config_realtime_process([0, 1, 2, 3], 5)
set_realtime_priority(5)
if sm is None: if sm is None:
sm = messaging.SubMaster(['liveLocationKalman', 'carState'], poll=['liveLocationKalman']) sm = messaging.SubMaster(['liveLocationKalman', 'carState'], poll=['liveLocationKalman'])
@ -178,7 +175,6 @@ def main(sm=None, pm=None):
angle_offset = clip(math.degrees(x[States.ANGLE_OFFSET] + x[States.ANGLE_OFFSET_FAST]), angle_offset - MAX_ANGLE_OFFSET_DELTA, angle_offset + MAX_ANGLE_OFFSET_DELTA) angle_offset = clip(math.degrees(x[States.ANGLE_OFFSET] + x[States.ANGLE_OFFSET_FAST]), angle_offset - MAX_ANGLE_OFFSET_DELTA, angle_offset + MAX_ANGLE_OFFSET_DELTA)
msg = messaging.new_message('liveParameters') msg = messaging.new_message('liveParameters')
msg.logMonoTime = sm.logMonoTime['carState']
liveParameters = msg.liveParameters liveParameters = msg.liveParameters
liveParameters.posenetValid = True liveParameters.posenetValid = True

@ -6,7 +6,7 @@ libs = [common, cereal, messaging, visionipc,
'avformat', 'avcodec', 'swscale', 'avutil', 'avformat', 'avcodec', 'swscale', 'avutil',
'yuv', 'bz2', 'OpenCL', 'pthread'] 'yuv', 'bz2', 'OpenCL', 'pthread']
src = ['logger.cc', 'loggerd.cc'] src = ['logger.cc', 'loggerd.cc', 'video_writer.cc']
if arch == "larch64": if arch == "larch64":
src += ['omx_encoder.cc'] src += ['omx_encoder.cc']
libs += ['OmxCore', 'gsl', 'CB'] + gpucommon libs += ['OmxCore', 'gsl', 'CB'] + gpucommon

@ -324,7 +324,7 @@ OmxEncoder::OmxEncoder(const char* filename, CameraType type, int in_width, int
service_name = this->type == DriverCam ? "driverEncodeData" : service_name = this->type == DriverCam ? "driverEncodeData" :
(this->type == WideRoadCam ? "wideRoadEncodeData" : (this->type == WideRoadCam ? "wideRoadEncodeData" :
(this->remuxing ? "qRoadEncodeData" : "roadEncodeData")); (this->remuxing ? "qRoadEncodeData" : "roadEncodeData"));
pm = new PubMaster({service_name}); pm.reset(new PubMaster({service_name}));
} }
void OmxEncoder::callback_handler(OmxEncoder *e) { void OmxEncoder::callback_handler(OmxEncoder *e) {
@ -393,66 +393,12 @@ void OmxEncoder::write_and_broadcast_handler(OmxEncoder *e){
void OmxEncoder::handle_out_buf(OmxEncoder *e, OmxBuffer *out_buf) { void OmxEncoder::handle_out_buf(OmxEncoder *e, OmxBuffer *out_buf) {
int err; if (!(out_buf->header.nFlags & OMX_BUFFERFLAG_EOS) && e->writer) {
e->writer->write(out_buf->data,
if (out_buf->header.nFlags & OMX_BUFFERFLAG_CODECCONFIG) { out_buf->header.nFilledLen,
if (e->codec_config_len < out_buf->header.nFilledLen) { out_buf->header.nTimeStamp,
e->codec_config = (uint8_t *)realloc(e->codec_config, out_buf->header.nFilledLen); out_buf->header.nFlags & OMX_BUFFERFLAG_CODECCONFIG,
} out_buf->header.nFlags & OMX_BUFFERFLAG_SYNCFRAME);
e->codec_config_len = out_buf->header.nFilledLen;
memcpy(e->codec_config, out_buf->data, out_buf->header.nFilledLen);
// TODO: is still needed?
#ifdef QCOM2
out_buf->header.nTimeStamp = 0;
#endif
}
if (e->of) {
//printf("write %d flags 0x%x\n", out_buf->nFilledLen, out_buf->nFlags);
size_t written = util::safe_fwrite(out_buf->data, 1, out_buf->header.nFilledLen, e->of);
if (written != out_buf->header.nFilledLen) {
LOGE("failed to write file.errno=%d", errno);
}
}
if (e->remuxing) {
if (!e->wrote_codec_config && e->codec_config_len > 0) {
// extradata will be freed by av_free() in avcodec_free_context()
e->codec_ctx->extradata = (uint8_t*)av_mallocz(e->codec_config_len + AV_INPUT_BUFFER_PADDING_SIZE);
e->codec_ctx->extradata_size = e->codec_config_len;
memcpy(e->codec_ctx->extradata, e->codec_config, e->codec_config_len);
err = avcodec_parameters_from_context(e->out_stream->codecpar, e->codec_ctx);
assert(err >= 0);
err = avformat_write_header(e->ofmt_ctx, NULL);
assert(err >= 0);
e->wrote_codec_config = true;
}
if (out_buf->header.nTimeStamp > 0) {
// input timestamps are in microseconds
AVRational in_timebase = {1, 1000000};
AVPacket pkt;
av_init_packet(&pkt);
pkt.data = out_buf->data;
pkt.size = out_buf->header.nFilledLen;
enum AVRounding rnd = static_cast<enum AVRounding>(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt.pts = pkt.dts = av_rescale_q_rnd(out_buf->header.nTimeStamp, in_timebase, e->ofmt_ctx->streams[0]->time_base, rnd);
pkt.duration = av_rescale_q(50*1000, in_timebase, e->ofmt_ctx->streams[0]->time_base);
if (out_buf->header.nFlags & OMX_BUFFERFLAG_SYNCFRAME) {
pkt.flags |= AV_PKT_FLAG_KEY;
}
err = av_write_frame(e->ofmt_ctx, &pkt);
if (err < 0) { LOGW("ts encoder write issue"); }
av_free_packet(&pkt);
}
} }
} }
@ -527,49 +473,10 @@ int OmxEncoder::encode_frame(const uint8_t *y_ptr, const uint8_t *u_ptr, const u
} }
void OmxEncoder::encoder_open(const char* path) { void OmxEncoder::encoder_open(const char* path) {
int err;
snprintf(this->vid_path, sizeof(this->vid_path), "%s/%s", path, this->filename);
LOGD("encoder_open %s remuxing:%d", this->vid_path, this->remuxing);
if (this->remuxing) {
avformat_alloc_output_context2(&this->ofmt_ctx, NULL, NULL, this->vid_path);
assert(this->ofmt_ctx);
this->out_stream = avformat_new_stream(this->ofmt_ctx, NULL);
assert(this->out_stream);
// set codec correctly
av_register_all();
AVCodec *codec = NULL;
codec = avcodec_find_encoder(AV_CODEC_ID_H264);
assert(codec);
this->codec_ctx = avcodec_alloc_context3(codec);
assert(this->codec_ctx);
this->codec_ctx->width = this->width;
this->codec_ctx->height = this->height;
this->codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P;
this->codec_ctx->time_base = (AVRational){ 1, this->fps };
err = avio_open(&this->ofmt_ctx->pb, this->vid_path, AVIO_FLAG_WRITE);
assert(err >= 0);
this->wrote_codec_config = false;
} else {
if (this->write) { if (this->write) {
this->of = util::safe_fopen(this->vid_path, "wb"); writer.reset(new VideoWriter(path, this->filename, this->remuxing, this->width, this->height, this->fps, !this->remuxing, false));
assert(this->of);
}
} }
// create camera lock file
snprintf(this->lock_path, sizeof(this->lock_path), "%s/%s.lock", path, this->filename);
int lock_fd = HANDLE_EINTR(open(this->lock_path, O_RDWR | O_CREAT, 0664));
assert(lock_fd >= 0);
close(lock_fd);
// start writer threads // start writer threads
callback_handler_thread = std::thread(OmxEncoder::callback_handler, this); callback_handler_thread = std::thread(OmxEncoder::callback_handler, this);
write_handler_thread = std::thread(OmxEncoder::write_and_broadcast_handler, this); write_handler_thread = std::thread(OmxEncoder::write_and_broadcast_handler, this);
@ -597,19 +504,7 @@ void OmxEncoder::encoder_close() {
callback_handler_thread.join(); callback_handler_thread.join();
write_handler_thread.join(); write_handler_thread.join();
if (this->remuxing) { writer.reset();
av_write_trailer(this->ofmt_ctx);
avcodec_free_context(&this->codec_ctx);
avio_closep(&this->ofmt_ctx->pb);
avformat_free_context(this->ofmt_ctx);
} else {
if (this->of) {
util::safe_fflush(this->of);
fclose(this->of);
this->of = nullptr;
}
}
unlink(this->lock_path);
} }
this->is_open = false; this->is_open = false;
} }
@ -644,10 +539,6 @@ OmxEncoder::~OmxEncoder() {
free(write_buf); free(write_buf);
}; };
if (this->codec_config) {
free(this->codec_config);
}
if (this->downscale) { if (this->downscale) {
free(this->y_ptr2); free(this->y_ptr2);
free(this->u_ptr2); free(this->u_ptr2);

@ -6,12 +6,10 @@
#include <thread> #include <thread>
#include <OMX_Component.h> #include <OMX_Component.h>
extern "C" {
#include <libavformat/avformat.h>
}
#include "selfdrive/common/queue.h" #include "selfdrive/common/queue.h"
#include "selfdrive/loggerd/encoder.h" #include "selfdrive/loggerd/encoder.h"
#include "selfdrive/loggerd/video_writer.h"
struct OmxBuffer { struct OmxBuffer {
OMX_BUFFERHEADERTYPE header; OMX_BUFFERHEADERTYPE header;
@ -45,8 +43,6 @@ private:
int in_width_, in_height_; int in_width_, in_height_;
int width, height, fps; int width, height, fps;
char vid_path[1024];
char lock_path[1024];
bool is_open = false; bool is_open = false;
bool dirty = false; bool dirty = false;
bool write = false; bool write = false;
@ -54,17 +50,12 @@ private:
std::thread callback_handler_thread; std::thread callback_handler_thread;
std::thread write_handler_thread; std::thread write_handler_thread;
int segment_num = -1; int segment_num = -1;
PubMaster *pm; std::unique_ptr<PubMaster> pm;
const char *service_name; const char *service_name;
const char* filename; const char* filename;
FILE *of = nullptr;
CameraType type; CameraType type;
size_t codec_config_len;
uint8_t *codec_config = NULL;
bool wrote_codec_config;
std::mutex state_lock; std::mutex state_lock;
std::condition_variable state_cv; std::condition_variable state_cv;
OMX_STATETYPE state = OMX_StateLoaded; OMX_STATETYPE state = OMX_StateLoaded;
@ -80,10 +71,8 @@ private:
SafeQueue<OMX_BUFFERHEADERTYPE *> done_out; SafeQueue<OMX_BUFFERHEADERTYPE *> done_out;
SafeQueue<OmxBuffer *> to_write; SafeQueue<OmxBuffer *> to_write;
AVFormatContext *ofmt_ctx;
AVCodecContext *codec_ctx;
AVStream *out_stream;
bool remuxing; bool remuxing;
std::unique_ptr<VideoWriter> writer;
bool downscale; bool downscale;
uint8_t *y_ptr2, *u_ptr2, *v_ptr2; uint8_t *y_ptr2, *u_ptr2, *v_ptr2;

@ -25,32 +25,10 @@ extern "C" {
RawLogger::RawLogger(const char* filename, CameraType type, int in_width, int in_height, int fps, RawLogger::RawLogger(const char* filename, CameraType type, int in_width, int in_height, int fps,
int bitrate, bool h265, int out_width, int out_height, bool write) int bitrate, bool h265, int out_width, int out_height, bool write)
: in_width_(in_width), in_height_(in_height), filename(filename), fps(fps) { : in_width_(in_width), in_height_(in_height), filename(filename), fps(fps) {
// TODO: respect write arg // TODO: respect write arg
codec = avcodec_find_encoder(AV_CODEC_ID_FFVHUFF);
// codec = avcodec_find_encoder(AV_CODEC_ID_FFV1);
assert(codec);
codec_ctx = avcodec_alloc_context3(codec);
assert(codec_ctx);
codec_ctx->width = out_width;
codec_ctx->height = out_height;
codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P;
// codec_ctx->thread_count = 2;
// ffv1enc doesn't respect AV_PICTURE_TYPE_I. make every frame a key frame for now.
// codec_ctx->gop_size = 0;
codec_ctx->time_base = (AVRational){ 1, fps };
int err = avcodec_open2(codec_ctx, codec, NULL);
assert(err >= 0);
frame = av_frame_alloc(); frame = av_frame_alloc();
assert(frame); assert(frame);
frame->format = codec_ctx->pix_fmt; frame->format = AV_PIX_FMT_YUV420P;
frame->width = out_width; frame->width = out_width;
frame->height = out_height; frame->height = out_height;
frame->linesize[0] = out_width; frame->linesize[0] = out_width;
@ -63,60 +41,20 @@ RawLogger::RawLogger(const char* filename, CameraType type, int in_width, int in
} }
RawLogger::~RawLogger() { RawLogger::~RawLogger() {
encoder_close();
av_frame_free(&frame); av_frame_free(&frame);
avcodec_close(codec_ctx);
av_free(codec_ctx);
} }
void RawLogger::encoder_open(const char* path) { void RawLogger::encoder_open(const char* path) {
vid_path = util::string_format("%s/%s", path, filename); writer = new VideoWriter(path, this->filename, true, frame->width, frame->height, this->fps, false, true);
// write the header
// create camera lock file writer->write(NULL, 0, 0, true, false);
lock_path = util::string_format("%s/%s.lock", path, filename);
LOG("open %s\n", lock_path.c_str());
int lock_fd = HANDLE_EINTR(open(lock_path.c_str(), O_RDWR | O_CREAT, 0664));
assert(lock_fd >= 0);
close(lock_fd);
format_ctx = NULL;
avformat_alloc_output_context2(&format_ctx, NULL, "matroska", vid_path.c_str());
assert(format_ctx);
stream = avformat_new_stream(format_ctx, codec);
// AVStream *stream = avformat_new_stream(format_ctx, NULL);
assert(stream);
stream->id = 0;
stream->time_base = (AVRational){ 1, fps };
// codec_ctx->time_base = stream->time_base;
int err = avcodec_parameters_from_context(stream->codecpar, codec_ctx);
assert(err >= 0);
err = avio_open(&format_ctx->pb, vid_path.c_str(), AVIO_FLAG_WRITE);
assert(err >= 0);
err = avformat_write_header(format_ctx, NULL);
assert(err >= 0);
is_open = true; is_open = true;
counter = 0;
} }
void RawLogger::encoder_close() { void RawLogger::encoder_close() {
if (!is_open) return; if (!is_open) return;
delete writer;
int err = av_write_trailer(format_ctx);
assert(err == 0);
err = avio_closep(&format_ctx->pb);
assert(err == 0);
avformat_free_context(format_ctx);
format_ctx = NULL;
unlink(lock_path.c_str());
is_open = false; is_open = false;
} }
@ -124,23 +62,19 @@ int RawLogger::encode_frame(const uint8_t *y_ptr, const uint8_t *u_ptr, const ui
int in_width, int in_height, uint64_t ts) { int in_width, int in_height, uint64_t ts) {
assert(in_width == this->in_width_); assert(in_width == this->in_width_);
assert(in_height == this->in_height_); assert(in_height == this->in_height_);
AVPacket pkt;
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
if (downscale_buf.size() > 0) { if (downscale_buf.size() > 0) {
uint8_t *out_y = downscale_buf.data(); uint8_t *out_y = downscale_buf.data();
uint8_t *out_u = out_y + codec_ctx->width * codec_ctx->height; uint8_t *out_u = out_y + frame->width * frame->height;
uint8_t *out_v = out_u + (codec_ctx->width / 2) * (codec_ctx->height / 2); uint8_t *out_v = out_u + (frame->width / 2) * (frame->height / 2);
libyuv::I420Scale(y_ptr, in_width, libyuv::I420Scale(y_ptr, in_width,
u_ptr, in_width/2, u_ptr, in_width/2,
v_ptr, in_width/2, v_ptr, in_width/2,
in_width, in_height, in_width, in_height,
out_y, codec_ctx->width, out_y, frame->width,
out_u, codec_ctx->width/2, out_u, frame->width/2,
out_v, codec_ctx->width/2, out_v, frame->width/2,
codec_ctx->width, codec_ctx->height, frame->width, frame->height,
libyuv::kFilterNone); libyuv::kFilterNone);
frame->data[0] = out_y; frame->data[0] = out_y;
frame->data[1] = out_u; frame->data[1] = out_u;
@ -150,18 +84,22 @@ int RawLogger::encode_frame(const uint8_t *y_ptr, const uint8_t *u_ptr, const ui
frame->data[1] = (uint8_t*)u_ptr; frame->data[1] = (uint8_t*)u_ptr;
frame->data[2] = (uint8_t*)v_ptr; frame->data[2] = (uint8_t*)v_ptr;
} }
frame->pts = counter; frame->pts = counter*50*1000; // 50ms per frame
int ret = counter; int ret = counter;
int err = avcodec_send_frame(codec_ctx, frame); int err = avcodec_send_frame(writer->codec_ctx, frame);
if (ret < 0) { if (err < 0) {
LOGE("avcode_send_frame error %d", err); LOGE("avcodec_send_frame error %d", err);
ret = -1; ret = -1;
} }
AVPacket pkt;
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
while (ret >= 0) { while (ret >= 0) {
err = avcodec_receive_packet(codec_ctx, &pkt); err = avcodec_receive_packet(writer->codec_ctx, &pkt);
if (err == AVERROR_EOF) { if (err == AVERROR_EOF) {
break; break;
} else if (err == AVERROR(EAGAIN)) { } else if (err == AVERROR(EAGAIN)) {
@ -174,18 +112,9 @@ int RawLogger::encode_frame(const uint8_t *y_ptr, const uint8_t *u_ptr, const ui
break; break;
} }
av_packet_rescale_ts(&pkt, codec_ctx->time_base, stream->time_base); writer->write(pkt.data, pkt.size, pkt.pts, false, pkt.flags & AV_PKT_FLAG_KEY);
pkt.stream_index = 0;
err = av_interleaved_write_frame(format_ctx, &pkt);
if (err < 0) {
LOGE("av_interleaved_write_frame %d", err);
ret = -1;
} else {
counter++; counter++;
} }
}
av_packet_unref(&pkt); av_packet_unref(&pkt);
return ret; return ret;
} }

@ -12,6 +12,7 @@ extern "C" {
} }
#include "selfdrive/loggerd/encoder.h" #include "selfdrive/loggerd/encoder.h"
#include "selfdrive/loggerd/video_writer.h"
class RawLogger : public VideoEncoder { class RawLogger : public VideoEncoder {
public: public:
@ -31,14 +32,9 @@ private:
bool is_open = false; bool is_open = false;
int in_width_, in_height_; int in_width_, in_height_;
std::string vid_path, lock_path;
const AVCodec *codec = NULL;
AVCodecContext *codec_ctx = NULL;
AVStream *stream = NULL;
AVFormatContext *format_ctx = NULL;
AVFrame *frame = NULL; AVFrame *frame = NULL;
std::vector<uint8_t> downscale_buf; std::vector<uint8_t> downscale_buf;
VideoWriter *writer = NULL;
}; };

@ -0,0 +1,118 @@
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#include <cassert>
#include <cstdlib>
#include "selfdrive/loggerd/video_writer.h"
#include "selfdrive/common/swaglog.h"
#include "selfdrive/common/util.h"
VideoWriter::VideoWriter(const char *path, const char *filename, bool remuxing, int width, int height, int fps, bool h265, bool raw)
: remuxing(remuxing), raw(raw) {
vid_path = util::string_format("%s/%s", path, filename);
lock_path = util::string_format("%s/%s.lock", path, filename);
int lock_fd = HANDLE_EINTR(open(lock_path.c_str(), O_RDWR | O_CREAT, 0664));
assert(lock_fd >= 0);
close(lock_fd);
LOGD("encoder_open %s remuxing:%d", this->vid_path.c_str(), this->remuxing);
if (this->remuxing) {
avformat_alloc_output_context2(&this->ofmt_ctx, NULL, raw ? "matroska" : NULL, this->vid_path.c_str());
assert(this->ofmt_ctx);
// set codec correctly. needed?
av_register_all();
AVCodec *codec = NULL;
assert(!h265);
codec = avcodec_find_encoder(raw ? AV_CODEC_ID_FFVHUFF : AV_CODEC_ID_H264);
assert(codec);
this->codec_ctx = avcodec_alloc_context3(codec);
assert(this->codec_ctx);
this->codec_ctx->width = width;
this->codec_ctx->height = height;
this->codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P;
this->codec_ctx->time_base = (AVRational){ 1, fps };
if (raw) {
// since the codec is actually used, we open it
int err = avcodec_open2(this->codec_ctx, codec, NULL);
assert(err >= 0);
}
this->out_stream = avformat_new_stream(this->ofmt_ctx, raw ? codec : NULL);
assert(this->out_stream);
int err = avio_open(&this->ofmt_ctx->pb, this->vid_path.c_str(), AVIO_FLAG_WRITE);
assert(err >= 0);
this->wrote_codec_config = false;
} else {
this->of = util::safe_fopen(this->vid_path.c_str(), "wb");
assert(this->of);
}
}
void VideoWriter::write(uint8_t *data, int len, long long timestamp, bool codecconfig, bool keyframe) {
if (of && data) {
size_t written = util::safe_fwrite(data, 1, len, of);
if (written != len) {
LOGE("failed to write file.errno=%d", errno);
}
}
if (remuxing) {
if (codecconfig) {
if (data) {
codec_ctx->extradata = (uint8_t*)av_mallocz(len + AV_INPUT_BUFFER_PADDING_SIZE);
codec_ctx->extradata_size = len;
memcpy(codec_ctx->extradata, data, len);
}
int err = avcodec_parameters_from_context(out_stream->codecpar, codec_ctx);
assert(err >= 0);
err = avformat_write_header(ofmt_ctx, NULL);
assert(err >= 0);
} else {
// input timestamps are in microseconds
AVRational in_timebase = {1, 1000000};
AVPacket pkt;
av_init_packet(&pkt);
pkt.data = data;
pkt.size = len;
enum AVRounding rnd = static_cast<enum AVRounding>(AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
pkt.pts = pkt.dts = av_rescale_q_rnd(timestamp, in_timebase, ofmt_ctx->streams[0]->time_base, rnd);
pkt.duration = av_rescale_q(50*1000, in_timebase, ofmt_ctx->streams[0]->time_base);
if (keyframe) {
pkt.flags |= AV_PKT_FLAG_KEY;
}
// TODO: can use av_write_frame for non raw?
int err = av_interleaved_write_frame(ofmt_ctx, &pkt);
if (err < 0) { LOGW("ts encoder write issue"); }
av_free_packet(&pkt);
}
}
}
VideoWriter::~VideoWriter() {
if (this->remuxing) {
if (this->raw) { avcodec_close(this->codec_ctx); }
int err = av_write_trailer(this->ofmt_ctx);
if (err != 0) LOGE("av_write_trailer failed %d", err);
avcodec_free_context(&this->codec_ctx);
err = avio_closep(&this->ofmt_ctx->pb);
if (err != 0) LOGE("avio_closep failed %d", err);
avformat_free_context(this->ofmt_ctx);
} else {
util::safe_fflush(this->of);
fclose(this->of);
this->of = nullptr;
}
unlink(this->lock_path.c_str());
}

@ -0,0 +1,25 @@
#pragma once
#include <string>
extern "C" {
#include <libavformat/avformat.h>
}
class VideoWriter {
public:
VideoWriter(const char *path, const char *filename, bool remuxing, int width, int height, int fps, bool h265, bool raw);
void write(uint8_t *data, int len, long long timestamp, bool codecconfig, bool keyframe);
~VideoWriter();
AVCodecContext *codec_ctx;
private:
std::string vid_path, lock_path;
FILE *of = nullptr;
AVFormatContext *ofmt_ctx;
AVStream *out_stream;
bool remuxing, raw;
bool wrote_codec_config;
};

@ -29,7 +29,7 @@ def build(spinner: Spinner, dirty: bool = False) -> None:
j_flag = "" if nproc is None else f"-j{nproc - 1}" j_flag = "" if nproc is None else f"-j{nproc - 1}"
for retry in [True, False]: for retry in [True, False]:
scons = subprocess.Popen(["scons", j_flag, "--cache-populate"], cwd=BASEDIR, env=env, stderr=subprocess.PIPE) scons: subprocess.Popen = subprocess.Popen(["scons", j_flag, "--cache-populate"], cwd=BASEDIR, env=env, stderr=subprocess.PIPE)
assert scons.stderr is not None assert scons.stderr is not None
compile_output = [] compile_output = []

@ -130,7 +130,6 @@ def manager_thread() -> None:
ensure_running(managed_processes.values(), started=False, not_run=ignore) ensure_running(managed_processes.values(), started=False, not_run=ignore)
started_prev = False
sm = messaging.SubMaster(['deviceState', 'carParams'], poll=['deviceState']) sm = messaging.SubMaster(['deviceState', 'carParams'], poll=['deviceState'])
pm = messaging.PubMaster(['managerState']) pm = messaging.PubMaster(['managerState'])
@ -141,13 +140,6 @@ def manager_thread() -> None:
driverview = params.get_bool("IsDriverViewEnabled") driverview = params.get_bool("IsDriverViewEnabled")
ensure_running(managed_processes.values(), started=started, driverview=driverview, notcar=sm['carParams'].notCar, not_run=ignore) ensure_running(managed_processes.values(), started=started, driverview=driverview, notcar=sm['carParams'].notCar, not_run=ignore)
# trigger an update after going offroad
if started_prev and not started and 'updated' in managed_processes:
os.sync()
managed_processes['updated'].signal(signal.SIGHUP)
started_prev = started
running = ' '.join("%s%s\u001b[0m" % ("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name) running = ' '.join("%s%s\u001b[0m" % ("\u001b[32m" if p.proc.is_alive() else "\u001b[31m", p.name)
for p in managed_processes.values() if p.proc) for p in managed_processes.values() if p.proc)
print(running) print(running)

@ -69,7 +69,8 @@ class ManagerProcess(ABC):
unkillable = False unkillable = False
daemon = False daemon = False
sigkill = False sigkill = False
persistent = False onroad = True
offroad = False
driverview = False driverview = False
notcar = False notcar = False
proc: Optional[Process] = None proc: Optional[Process] = None
@ -77,7 +78,7 @@ class ManagerProcess(ABC):
name = "" name = ""
last_watchdog_time = 0 last_watchdog_time = 0
watchdog_max_dt = None watchdog_max_dt: Optional[int] = None
watchdog_seen = False watchdog_seen = False
shutting_down = False shutting_down = False
@ -183,12 +184,13 @@ class ManagerProcess(ABC):
class NativeProcess(ManagerProcess): class NativeProcess(ManagerProcess):
def __init__(self, name, cwd, cmdline, enabled=True, persistent=False, driverview=False, notcar=False, unkillable=False, sigkill=False, watchdog_max_dt=None): def __init__(self, name, cwd, cmdline, enabled=True, onroad=True, offroad=False, driverview=False, notcar=False, unkillable=False, sigkill=False, watchdog_max_dt=None):
self.name = name self.name = name
self.cwd = cwd self.cwd = cwd
self.cmdline = cmdline self.cmdline = cmdline
self.enabled = enabled self.enabled = enabled
self.persistent = persistent self.onroad = onroad
self.offroad = offroad
self.driverview = driverview self.driverview = driverview
self.notcar = notcar self.notcar = notcar
self.unkillable = unkillable self.unkillable = unkillable
@ -215,11 +217,12 @@ class NativeProcess(ManagerProcess):
class PythonProcess(ManagerProcess): class PythonProcess(ManagerProcess):
def __init__(self, name, module, enabled=True, persistent=False, driverview=False, notcar=False, unkillable=False, sigkill=False, watchdog_max_dt=None): def __init__(self, name, module, enabled=True, onroad=True, offroad=False, driverview=False, notcar=False, unkillable=False, sigkill=False, watchdog_max_dt=None):
self.name = name self.name = name
self.module = module self.module = module
self.enabled = enabled self.enabled = enabled
self.persistent = persistent self.onroad = onroad
self.offroad = offroad
self.driverview = driverview self.driverview = driverview
self.notcar = notcar self.notcar = notcar
self.unkillable = unkillable self.unkillable = unkillable
@ -254,7 +257,8 @@ class DaemonProcess(ManagerProcess):
self.module = module self.module = module
self.param_name = param_name self.param_name = param_name
self.enabled = enabled self.enabled = enabled
self.persistent = True self.onroad = True
self.offroad = True
def prepare(self) -> None: def prepare(self) -> None:
pass pass
@ -293,23 +297,23 @@ def ensure_running(procs: ValuesView[ManagerProcess], started: bool, driverview:
not_run = [] not_run = []
for p in procs: for p in procs:
if p.name in not_run: # Conditions that make a process run
p.stop(block=False) run = any((
elif not p.enabled: p.offroad and not started,
p.stop(block=False) p.onroad and started,
elif p.persistent: p.driverview and driverview,
p.start() p.notcar and notcar,
elif p.driverview and driverview: ))
p.start()
elif p.notcar: # Conditions that block a process from starting
if notcar: run = run and not any((
p.start() not p.enabled,
else: p.name in not_run,
p.stop(block=False) ))
elif started:
if run:
p.start() p.start()
else: else:
p.stop(block=False) p.stop(block=False)
p.check_watchdog(started) p.check_watchdog(started)

@ -14,32 +14,32 @@ procs = [
NativeProcess("logcatd", "selfdrive/logcatd", ["./logcatd"]), NativeProcess("logcatd", "selfdrive/logcatd", ["./logcatd"]),
NativeProcess("loggerd", "selfdrive/loggerd", ["./loggerd"]), NativeProcess("loggerd", "selfdrive/loggerd", ["./loggerd"]),
NativeProcess("modeld", "selfdrive/modeld", ["./modeld"]), NativeProcess("modeld", "selfdrive/modeld", ["./modeld"]),
NativeProcess("navd", "selfdrive/ui/navd", ["./navd"], persistent=True), NativeProcess("navd", "selfdrive/ui/navd", ["./navd"], offroad=True),
NativeProcess("proclogd", "selfdrive/proclogd", ["./proclogd"]), NativeProcess("proclogd", "selfdrive/proclogd", ["./proclogd"]),
NativeProcess("sensord", "selfdrive/sensord", ["./sensord"], enabled=not PC), NativeProcess("sensord", "selfdrive/sensord", ["./sensord"], enabled=not PC),
NativeProcess("ubloxd", "selfdrive/locationd", ["./ubloxd"], enabled=(not PC or WEBCAM)), NativeProcess("ubloxd", "selfdrive/locationd", ["./ubloxd"], enabled=(not PC or WEBCAM)),
NativeProcess("ui", "selfdrive/ui", ["./ui"], persistent=True, watchdog_max_dt=(5 if TICI else None)), NativeProcess("ui", "selfdrive/ui", ["./ui"], offroad=True, watchdog_max_dt=(5 if TICI else None)),
NativeProcess("soundd", "selfdrive/ui/soundd", ["./soundd"], persistent=True), NativeProcess("soundd", "selfdrive/ui/soundd", ["./soundd"], offroad=True),
NativeProcess("locationd", "selfdrive/locationd", ["./locationd"]), NativeProcess("locationd", "selfdrive/locationd", ["./locationd"]),
NativeProcess("boardd", "selfdrive/boardd", ["./boardd"], enabled=False), NativeProcess("boardd", "selfdrive/boardd", ["./boardd"], enabled=False),
PythonProcess("calibrationd", "selfdrive.locationd.calibrationd"), PythonProcess("calibrationd", "selfdrive.locationd.calibrationd"),
PythonProcess("controlsd", "selfdrive.controls.controlsd"), PythonProcess("controlsd", "selfdrive.controls.controlsd"),
PythonProcess("deleter", "selfdrive.loggerd.deleter", persistent=True), PythonProcess("deleter", "selfdrive.loggerd.deleter", offroad=True),
PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", enabled=(not PC or WEBCAM), driverview=True), PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", enabled=(not PC or WEBCAM), driverview=True),
PythonProcess("logmessaged", "selfdrive.logmessaged", persistent=True), PythonProcess("logmessaged", "selfdrive.logmessaged", offroad=True),
PythonProcess("pandad", "selfdrive.boardd.pandad", persistent=True), PythonProcess("pandad", "selfdrive.boardd.pandad", offroad=True),
PythonProcess("paramsd", "selfdrive.locationd.paramsd"), PythonProcess("paramsd", "selfdrive.locationd.paramsd"),
PythonProcess("plannerd", "selfdrive.controls.plannerd"), PythonProcess("plannerd", "selfdrive.controls.plannerd"),
PythonProcess("radard", "selfdrive.controls.radard"), PythonProcess("radard", "selfdrive.controls.radard"),
PythonProcess("thermald", "selfdrive.thermald.thermald", persistent=True), PythonProcess("thermald", "selfdrive.thermald.thermald", offroad=True),
PythonProcess("timezoned", "selfdrive.timezoned", enabled=TICI, persistent=True), PythonProcess("timezoned", "selfdrive.timezoned", enabled=TICI, offroad=True),
PythonProcess("tombstoned", "selfdrive.tombstoned", enabled=not PC, persistent=True), PythonProcess("tombstoned", "selfdrive.tombstoned", enabled=not PC, offroad=True),
PythonProcess("updated", "selfdrive.updated", enabled=not PC, persistent=True), PythonProcess("updated", "selfdrive.updated", enabled=not PC, onroad=False, offroad=True),
PythonProcess("uploader", "selfdrive.loggerd.uploader", persistent=True), PythonProcess("uploader", "selfdrive.loggerd.uploader", offroad=True),
PythonProcess("statsd", "selfdrive.statsd", persistent=True), PythonProcess("statsd", "selfdrive.statsd", offroad=True),
NativeProcess("bridge", "cereal/messaging", ["./bridge"], notcar=True), NativeProcess("bridge", "cereal/messaging", ["./bridge"], onroad=False, notcar=True),
PythonProcess("webjoystick", "tools.joystick.web", notcar=True), PythonProcess("webjoystick", "tools.joystick.web", onroad=False, notcar=True),
# Experimental # Experimental
PythonProcess("rawgpsd", "selfdrive.sensord.rawgps.rawgpsd", enabled=os.path.isfile("/persist/comma/use-quectel-rawgps")), PythonProcess("rawgpsd", "selfdrive.sensord.rawgps.rawgpsd", enabled=os.path.isfile("/persist/comma/use-quectel-rawgps")),

@ -129,11 +129,6 @@ void run_model(ModelState &model, VisionIpcClient &vipc_client_main, VisionIpcCl
vec_desire[desire] = 1.0; vec_desire[desire] = 1.0;
} }
double mt1 = millis_since_boot();
ModelOutput *model_output = model_eval_frame(&model, buf_main, buf_extra, model_transform_main, model_transform_extra, vec_desire);
double mt2 = millis_since_boot();
float model_execution_time = (mt2 - mt1) / 1000.0;
// tracked dropped frames // tracked dropped frames
uint32_t vipc_dropped_frames = meta_main.frame_id - last_vipc_frame_id - 1; uint32_t vipc_dropped_frames = meta_main.frame_id - last_vipc_frame_id - 1;
float frames_dropped = frame_dropped_filter.update((float)std::min(vipc_dropped_frames, 10U)); float frames_dropped = frame_dropped_filter.update((float)std::min(vipc_dropped_frames, 10U));
@ -144,10 +139,22 @@ void run_model(ModelState &model, VisionIpcClient &vipc_client_main, VisionIpcCl
run_count++; run_count++;
float frame_drop_ratio = frames_dropped / (1 + frames_dropped); float frame_drop_ratio = frames_dropped / (1 + frames_dropped);
bool prepare_only = vipc_dropped_frames > 0;
if (prepare_only) {
LOGE("skipping model eval. Dropped %d frames", vipc_dropped_frames);
}
double mt1 = millis_since_boot();
ModelOutput *model_output = model_eval_frame(&model, buf_main, buf_extra, model_transform_main, model_transform_extra, vec_desire, prepare_only);
double mt2 = millis_since_boot();
float model_execution_time = (mt2 - mt1) / 1000.0;
if (model_output != nullptr) {
model_publish(pm, meta_main.frame_id, meta_extra.frame_id, frame_id, frame_drop_ratio, *model_output, meta_main.timestamp_eof, model_execution_time, model_publish(pm, meta_main.frame_id, meta_extra.frame_id, frame_id, frame_drop_ratio, *model_output, meta_main.timestamp_eof, model_execution_time,
kj::ArrayPtr<const float>(model.output.data(), model.output.size()), live_calib_seen); kj::ArrayPtr<const float>(model.output.data(), model.output.size()), live_calib_seen);
posenet_publish(pm, meta_main.frame_id, vipc_dropped_frames, *model_output, meta_main.timestamp_eof, live_calib_seen); posenet_publish(pm, meta_main.frame_id, vipc_dropped_frames, *model_output, meta_main.timestamp_eof, live_calib_seen);
}
//printf("model process: %.2fms, from last %.2fms, vipc_frame_id %u, frame_id, %u, frame_drop %.3f\n", mt2 - mt1, mt1 - last, extra.frame_id, frame_id, frame_drop_ratio); //printf("model process: %.2fms, from last %.2fms, vipc_frame_id %u, frame_id, %u, frame_drop %.3f\n", mt2 - mt1, mt1 - last, extra.frame_id, frame_id, frame_drop_ratio);
last = mt1; last = mt1;
@ -164,8 +171,8 @@ int main(int argc, char **argv) {
assert(ret == 0); assert(ret == 0);
} }
bool main_wide_camera = Hardware::TICI() ? Params().getBool("EnableWideCamera") : false; bool main_wide_camera = Params().getBool("EnableWideCamera");
bool use_extra_client = !main_wide_camera; bool use_extra_client = !main_wide_camera; // set for single camera mode
// cl init // cl init
cl_device_id device_id = cl_get_device_id(CL_DEVICE_TYPE_DEFAULT); cl_device_id device_id = cl_get_device_id(CL_DEVICE_TYPE_DEFAULT);

@ -56,7 +56,7 @@ void model_init(ModelState* s, cl_device_id device_id, cl_context context) {
} }
ModelOutput* model_eval_frame(ModelState* s, VisionBuf* buf, VisionBuf* wbuf, ModelOutput* model_eval_frame(ModelState* s, VisionBuf* buf, VisionBuf* wbuf,
const mat3 &transform, const mat3 &transform_wide, float *desire_in) { const mat3 &transform, const mat3 &transform_wide, float *desire_in, bool prepare_only) {
#ifdef DESIRE #ifdef DESIRE
if (desire_in != NULL) { if (desire_in != NULL) {
for (int i = 1; i < DESIRE_LEN; i++) { for (int i = 1; i < DESIRE_LEN; i++) {
@ -82,6 +82,11 @@ ModelOutput* model_eval_frame(ModelState* s, VisionBuf* buf, VisionBuf* wbuf,
s->m->addExtra(net_extra_buf, s->wide_frame->buf_size); s->m->addExtra(net_extra_buf, s->wide_frame->buf_size);
LOGT("Extra image added"); LOGT("Extra image added");
} }
if (prepare_only) {
return nullptr;
}
s->m->execute(); s->m->execute();
LOGT("Execution finished"); LOGT("Execution finished");

@ -268,7 +268,7 @@ struct ModelState {
void model_init(ModelState* s, cl_device_id device_id, cl_context context); void model_init(ModelState* s, cl_device_id device_id, cl_context context);
ModelOutput *model_eval_frame(ModelState* s, VisionBuf* buf, VisionBuf* buf_wide, ModelOutput *model_eval_frame(ModelState* s, VisionBuf* buf, VisionBuf* buf_wide,
const mat3 &transform, const mat3 &transform_wide, float *desire_in); const mat3 &transform, const mat3 &transform_wide, float *desire_in, bool prepare_only);
void model_free(ModelState* s); void model_free(ModelState* s);
void model_publish(PubMaster &pm, uint32_t vipc_frame_id, uint32_t vipc_frame_id_extra, uint32_t frame_id, float frame_drop, void model_publish(PubMaster &pm, uint32_t vipc_frame_id, uint32_t vipc_frame_id_extra, uint32_t frame_id, float frame_drop,
const ModelOutput &net_outputs, uint64_t timestamp_eof, const ModelOutput &net_outputs, uint64_t timestamp_eof,

@ -25,6 +25,11 @@ def write(d):
def run_loop(m): def run_loop(m):
ishapes = [[1]+ii.shape[1:] for ii in m.get_inputs()] ishapes = [[1]+ii.shape[1:] for ii in m.get_inputs()]
keys = [x.name for x in m.get_inputs()] keys = [x.name for x in m.get_inputs()]
# run once to initialize CUDA provider
if "CUDAExecutionProvider" in m.get_providers():
m.run(None, dict(zip(keys, [np.zeros(shp, dtype=np.float32) for shp in ishapes])))
print("ready to run onnx model", keys, ishapes, file=sys.stderr) print("ready to run onnx model", keys, ishapes, file=sys.stderr)
while 1: while 1:
inputs = [] inputs = []

@ -2,6 +2,7 @@
import time import time
import unittest import unittest
import numpy as np import numpy as np
import random
import cereal.messaging as messaging import cereal.messaging as messaging
from cereal.visionipc.visionipc_pyx import VisionIpcServer, VisionStreamType # pylint: disable=no-name-in-module, import-error from cereal.visionipc.visionipc_pyx import VisionIpcServer, VisionStreamType # pylint: disable=no-name-in-module, import-error
@ -26,7 +27,7 @@ class TestModeld(unittest.TestCase):
self.vipc_server.start_listener() self.vipc_server.start_listener()
self.sm = messaging.SubMaster(['modelV2', 'cameraOdometry']) self.sm = messaging.SubMaster(['modelV2', 'cameraOdometry'])
self.pm = messaging.PubMaster(['roadCameraState', 'wideRoadCameraState', 'driverCameraState', 'liveCalibration', 'lateralPlan']) self.pm = messaging.PubMaster(['roadCameraState', 'wideRoadCameraState', 'liveCalibration', 'lateralPlan'])
managed_processes['modeld'].start() managed_processes['modeld'].start()
time.sleep(0.2) time.sleep(0.2)
@ -36,23 +37,33 @@ class TestModeld(unittest.TestCase):
managed_processes['modeld'].stop() managed_processes['modeld'].stop()
del self.vipc_server del self.vipc_server
def test_modeld(self): def _send_frames(self, frame_id, cams=None):
for n in range(1, 500): if cams is None:
for cam in ('roadCameraState', 'wideRoadCameraState'): cams = ('roadCameraState', 'wideRoadCameraState')
cs = None
for cam in cams:
msg = messaging.new_message(cam) msg = messaging.new_message(cam)
cs = getattr(msg, cam) cs = getattr(msg, cam)
cs.frameId = n cs.frameId = frame_id
cs.timestampSof = int((n * DT_MDL) * 1e9) cs.timestampSof = int((frame_id * DT_MDL) * 1e9)
cs.timestampEof = int(cs.timestampSof + (DT_MDL * 1e9)) cs.timestampEof = int(cs.timestampSof + (DT_MDL * 1e9))
self.pm.send(msg.which(), msg) self.pm.send(msg.which(), msg)
self.vipc_server.send(VIPC_STREAM[msg.which()], IMG_BYTES, cs.frameId, self.vipc_server.send(VIPC_STREAM[msg.which()], IMG_BYTES, cs.frameId,
cs.timestampSof, cs.timestampEof) cs.timestampSof, cs.timestampEof)
return cs
def _wait(self):
self.sm.update(5000) self.sm.update(5000)
if self.sm['modelV2'].frameId != self.sm['cameraOdometry'].frameId: if self.sm['modelV2'].frameId != self.sm['cameraOdometry'].frameId:
self.sm.update(1000) self.sm.update(1000)
def test_modeld(self):
for n in range(1, 500):
cs = self._send_frames(n)
self._wait()
mdl = self.sm['modelV2'] mdl = self.sm['modelV2']
self.assertEqual(mdl.frameId, n) self.assertEqual(mdl.frameId, n)
self.assertEqual(mdl.frameIdExtra, n) self.assertEqual(mdl.frameIdExtra, n)
@ -64,8 +75,32 @@ class TestModeld(unittest.TestCase):
self.assertEqual(odo.frameId, n) self.assertEqual(odo.frameId, n)
self.assertEqual(odo.timestampEof, cs.timestampEof) self.assertEqual(odo.timestampEof, cs.timestampEof)
def test_skipped_frames(self): def test_dropped_frames(self):
pass """
modeld should only run on consecutive road frames
"""
frame_id = -1
road_frames = list()
for n in range(1, 50):
if (random.random() < 0.1) and n > 3:
cams = random.choice([(), ('wideRoadCameraState', )])
self._send_frames(n, cams)
else:
self._send_frames(n)
road_frames.append(n)
self._wait()
if len(road_frames) < 3 or road_frames[-1] - road_frames[-2] == 1:
frame_id = road_frames[-1]
mdl = self.sm['modelV2']
odo = self.sm['cameraOdometry']
self.assertEqual(mdl.frameId, frame_id)
self.assertEqual(mdl.frameIdExtra, frame_id)
self.assertEqual(odo.frameId, frame_id)
if n != frame_id:
self.assertFalse(self.sm.updated['modelV2'])
self.assertFalse(self.sm.updated['cameraOdometry'])
if __name__ == "__main__": if __name__ == "__main__":

@ -11,7 +11,7 @@ from common.realtime import set_core_affinity, set_realtime_priority
# openpilot processes # openpilot processes
def main() -> NoReturn: def main() -> NoReturn:
set_core_affinity(int(os.getenv("CORE", "3"))) set_core_affinity([int(os.getenv("CORE", "3")), ])
set_realtime_priority(1) set_realtime_priority(1)
while True: while True:

@ -347,6 +347,7 @@ def setup_env(simulation=False):
params.put_bool("OpenpilotEnabledToggle", True) params.put_bool("OpenpilotEnabledToggle", True)
params.put_bool("Passive", False) params.put_bool("Passive", False)
params.put_bool("DisengageOnAccelerator", True) params.put_bool("DisengageOnAccelerator", True)
params.put_bool("EnableWideCamera", False)
os.environ["NO_RADAR_SLEEP"] = "1" os.environ["NO_RADAR_SLEEP"] = "1"
os.environ["REPLAY"] = "1" os.environ["REPLAY"] = "1"

@ -1 +1 @@
ea48ff4478914b6aff56a979a647fe13b4993711 8d369bed132b691e1c000a726ab253ce7cbf8e09

@ -36,6 +36,8 @@ def replay_panda_states(s, msgs):
cp = [m for m in msgs if m.which() == 'carParams'][0].carParams cp = [m for m in msgs if m.which() == 'carParams'][0].carParams
if len(cp.safetyConfigs): if len(cp.safetyConfigs):
safety_param = cp.safetyConfigs[0].safetyParam safety_param = cp.safetyConfigs[0].safetyParam
if cp.safetyConfigs[0].safetyParamDEPRECATED != 0:
safety_param = cp.safetyConfigs[0].safetyParamDEPRECATED
else: else:
safety_param = cp.safetyParamDEPRECATED safety_param = cp.safetyParamDEPRECATED
@ -112,15 +114,15 @@ def replay_service(s, msgs):
def replay_cameras(lr, frs): def replay_cameras(lr, frs):
eon_cameras = [ eon_cameras = [
("roadCameraState", DT_MDL, eon_f_frame_size, VisionStreamType.VISION_STREAM_ROAD), ("roadCameraState", DT_MDL, eon_f_frame_size, VisionStreamType.VISION_STREAM_ROAD, True),
("driverCameraState", DT_DMON, eon_d_frame_size, VisionStreamType.VISION_STREAM_DRIVER), ("driverCameraState", DT_DMON, eon_d_frame_size, VisionStreamType.VISION_STREAM_DRIVER, False),
] ]
tici_cameras = [ tici_cameras = [
("roadCameraState", DT_MDL, tici_f_frame_size, VisionStreamType.VISION_STREAM_ROAD), ("roadCameraState", DT_MDL, tici_f_frame_size, VisionStreamType.VISION_STREAM_ROAD, True),
("driverCameraState", DT_MDL, tici_d_frame_size, VisionStreamType.VISION_STREAM_DRIVER), ("driverCameraState", DT_MDL, tici_d_frame_size, VisionStreamType.VISION_STREAM_DRIVER, False),
] ]
def replay_camera(s, stream, dt, vipc_server, frames, size): def replay_camera(s, stream, dt, vipc_server, frames, size, use_extra_client):
pm = messaging.PubMaster([s, ]) pm = messaging.PubMaster([s, ])
rk = Ratekeeper(1 / dt, print_delay_threshold=None) rk = Ratekeeper(1 / dt, print_delay_threshold=None)
@ -139,6 +141,8 @@ def replay_cameras(lr, frs):
pm.send(s, m) pm.send(s, m)
vipc_server.send(stream, img, msg.frameId, msg.timestampSof, msg.timestampEof) vipc_server.send(stream, img, msg.frameId, msg.timestampSof, msg.timestampEof)
if use_extra_client:
vipc_server.send(VisionStreamType.VISION_STREAM_WIDE_ROAD, img, msg.frameId, msg.timestampSof, msg.timestampEof)
init_data = [m for m in lr if m.which() == 'initData'][0] init_data = [m for m in lr if m.which() == 'initData'][0]
cameras = tici_cameras if (init_data.initData.deviceType == 'tici') else eon_cameras cameras = tici_cameras if (init_data.initData.deviceType == 'tici') else eon_cameras
@ -146,7 +150,7 @@ def replay_cameras(lr, frs):
# init vipc server and cameras # init vipc server and cameras
p = [] p = []
vs = VisionIpcServer("camerad") vs = VisionIpcServer("camerad")
for (s, dt, size, stream) in cameras: for (s, dt, size, stream, use_extra_client) in cameras:
fr = frs.get(s, None) fr = frs.get(s, None)
frames = None frames = None
@ -158,8 +162,10 @@ def replay_cameras(lr, frs):
frames.append(img.flatten().tobytes()) frames.append(img.flatten().tobytes())
vs.create_buffers(stream, 40, False, size[0], size[1]) vs.create_buffers(stream, 40, False, size[0], size[1])
if use_extra_client:
vs.create_buffers(VisionStreamType.VISION_STREAM_WIDE_ROAD, 40, False, size[0], size[1])
p.append(multiprocessing.Process(target=replay_camera, p.append(multiprocessing.Process(target=replay_camera,
args=(s, stream, dt, vs, frames, size))) args=(s, stream, dt, vs, frames, size, use_extra_client)))
# hack to make UI work # hack to make UI work
vs.create_buffers(VisionStreamType.VISION_STREAM_RGB_ROAD, 4, True, eon_f_frame_size[0], eon_f_frame_size[1]) vs.create_buffers(VisionStreamType.VISION_STREAM_RGB_ROAD, 4, True, eon_f_frame_size[0], eon_f_frame_size[1])
@ -218,6 +224,11 @@ def regen_segment(lr, frs=None, outdir=FAKEDATA):
} }
try: try:
# TODO: make first run of onnxruntime CUDA provider fast
managed_processes["modeld"].start()
managed_processes["dmonitoringmodeld"].start()
time.sleep(5)
# start procs up # start procs up
ignore = list(fake_daemons.keys()) + ['ui', 'manage_athenad', 'uploader'] ignore = list(fake_daemons.keys()) + ['ui', 'manage_athenad', 'uploader']
ensure_running(managed_processes.values(), started=True, not_run=ignore) ensure_running(managed_processes.values(), started=True, not_run=ignore)

@ -33,11 +33,11 @@ original_segments = [
segments = [ segments = [
("BODY", "bd6a637565e91581|2022-04-04--22-05-08--0"), ("BODY", "bd6a637565e91581|2022-04-04--22-05-08--0"),
("HYUNDAI", "fakedata|2022-01-20--17-49-04--0"), ("HYUNDAI", "fakedata|2022-01-20--17-49-04--0"),
("TOYOTA", "fakedata|2022-01-20--17-50-51--0"), ("TOYOTA", "fakedata|2022-04-13--18-53-16--0"),
("TOYOTA2", "fakedata|2022-01-20--17-52-36--0"), ("TOYOTA2", "fakedata|2022-04-26--22-58-12--0"),
("TOYOTA3", "fakedata|2022-01-20--17-54-50--0"), ("TOYOTA3", "fakedata|2022-04-13--19-09-53--0"),
("HONDA", "fakedata|2022-01-20--17-56-40--0"), ("HONDA", "fakedata|2022-01-20--17-56-40--0"),
("HONDA2", "fakedata|2022-01-20--17-58-25--0"), ("HONDA2", "fakedata|2022-04-13--19-23-30--0"),
("CHRYSLER", "fakedata|2022-01-20--18-00-11--0"), ("CHRYSLER", "fakedata|2022-01-20--18-00-11--0"),
("SUBARU", "fakedata|2022-01-20--18-01-57--0"), ("SUBARU", "fakedata|2022-01-20--18-01-57--0"),
("GM", "fakedata|2022-01-20--18-03-41--0"), ("GM", "fakedata|2022-01-20--18-03-41--0"),

@ -26,8 +26,8 @@ PROCS = {
"./camerad": 41.0, "./camerad": 41.0,
"./locationd": 9.1, "./locationd": 9.1,
"selfdrive.controls.plannerd": 11.7, "selfdrive.controls.plannerd": 11.7,
"./_ui": 33.0, "./_ui": 18.4,
"selfdrive.locationd.paramsd": 5.0, "selfdrive.locationd.paramsd": 9.0,
"./_sensord": 6.17, "./_sensord": 6.17,
"selfdrive.controls.radard": 4.5, "selfdrive.controls.radard": 4.5,
"./_modeld": 4.48, "./_modeld": 4.48,
@ -205,8 +205,8 @@ class TestOnroad(unittest.TestCase):
result += "------------------------------------------------\n" result += "------------------------------------------------\n"
# TODO: this went up when plannerd cpu usage increased, why? # TODO: this went up when plannerd cpu usage increased, why?
cfgs = [ cfgs = [
("modelV2", 0.038, 0.036), ("modelV2", 0.050, 0.036),
("driverState", 0.035, 0.026), ("driverState", 0.050, 0.026),
] ]
for (s, instant_max, avg_max) in cfgs: for (s, instant_max, avg_max) in cfgs:
ts = [getattr(getattr(m, s), "modelExecutionTime") for m in self.lr if m.which() == s] ts = [getattr(getattr(m, s), "modelExecutionTime") for m in self.lr if m.which() == s]

@ -46,7 +46,7 @@ THERMAL_BANDS = OrderedDict({
}) })
# Override to highest thermal band when offroad and above this temp # Override to highest thermal band when offroad and above this temp
OFFROAD_DANGER_TEMP = 79.5 if TICI else 70.0 OFFROAD_DANGER_TEMP = 79.5
prev_offroad_states: Dict[str, Tuple[bool, Optional[str]]] = {} prev_offroad_states: Dict[str, Tuple[bool, Optional[str]]] = {}

@ -15,7 +15,7 @@ if arch == "Darwin":
del base_libs[base_libs.index('OpenCL')] del base_libs[base_libs.index('OpenCL')]
qt_env['FRAMEWORKS'] += ['OpenCL'] qt_env['FRAMEWORKS'] += ['OpenCL']
widgets_src = ["qt/util.cc", "qt/widgets/input.cc", "qt/widgets/drive_stats.cc", widgets_src = ["ui.cc", "qt/util.cc", "qt/widgets/input.cc", "qt/widgets/drive_stats.cc",
"qt/widgets/ssh_keys.cc", "qt/widgets/toggle.cc", "qt/widgets/controls.cc", "qt/widgets/ssh_keys.cc", "qt/widgets/toggle.cc", "qt/widgets/controls.cc",
"qt/widgets/offroad_alerts.cc", "qt/widgets/prime.cc", "qt/widgets/keyboard.cc", "qt/widgets/offroad_alerts.cc", "qt/widgets/prime.cc", "qt/widgets/keyboard.cc",
"qt/widgets/scrollview.cc", "qt/widgets/cameraview.cc", "#third_party/qrcode/QrCode.cc", "qt/api.cc", "qt/widgets/scrollview.cc", "qt/widgets/cameraview.cc", "#third_party/qrcode/QrCode.cc", "qt/api.cc",
@ -50,7 +50,7 @@ qt_env.Program("qt/text", ["qt/text.cc"], LIBS=qt_libs)
qt_env.Program("qt/spinner", ["qt/spinner.cc"], LIBS=qt_libs) qt_env.Program("qt/spinner", ["qt/spinner.cc"], LIBS=qt_libs)
# build main UI # build main UI
qt_src = ["main.cc", "ui.cc", "qt/sidebar.cc", "qt/onroad.cc", "qt/body.cc", qt_src = ["main.cc", "qt/sidebar.cc", "qt/onroad.cc", "qt/body.cc",
"qt/window.cc", "qt/home.cc", "qt/offroad/settings.cc", "qt/window.cc", "qt/home.cc", "qt/offroad/settings.cc",
"qt/offroad/onboarding.cc", "qt/offroad/driverview.cc"] "qt/offroad/onboarding.cc", "qt/offroad/driverview.cc"]
qt_env.Program("_ui", qt_src + [asset_obj], LIBS=qt_libs) qt_env.Program("_ui", qt_src + [asset_obj], LIBS=qt_libs)

@ -12,7 +12,7 @@ DriverViewWindow::DriverViewWindow(QWidget* parent) : QWidget(parent) {
layout = new QStackedLayout(this); layout = new QStackedLayout(this);
layout->setStackingMode(QStackedLayout::StackAll); layout->setStackingMode(QStackedLayout::StackAll);
cameraView = new CameraViewWidget("camerad", VISION_STREAM_RGB_DRIVER, true, this); cameraView = new CameraViewWidget("camerad", VISION_STREAM_DRIVER, true, this);
layout->addWidget(cameraView); layout->addWidget(cameraView);
scene = new DriverViewScene(this); scene = new DriverViewScene(this);

@ -20,7 +20,7 @@ OnroadWindow::OnroadWindow(QWidget *parent) : QWidget(parent) {
QStackedLayout *road_view_layout = new QStackedLayout; QStackedLayout *road_view_layout = new QStackedLayout;
road_view_layout->setStackingMode(QStackedLayout::StackAll); road_view_layout->setStackingMode(QStackedLayout::StackAll);
nvg = new NvgWindow(VISION_STREAM_RGB_ROAD, this); nvg = new NvgWindow(VISION_STREAM_ROAD, this);
road_view_layout->addWidget(nvg); road_view_layout->addWidget(nvg);
hud = new OnroadHud(this); hud = new OnroadHud(this);
road_view_layout->addWidget(hud); road_view_layout->addWidget(hud);
@ -97,7 +97,7 @@ void OnroadWindow::offroadTransition(bool offroad) {
// update stream type // update stream type
bool wide_cam = Hardware::TICI() && Params().getBool("EnableWideCamera"); bool wide_cam = Hardware::TICI() && Params().getBool("EnableWideCamera");
nvg->setStreamType(wide_cam ? VISION_STREAM_RGB_WIDE_ROAD : VISION_STREAM_RGB_ROAD); nvg->setStreamType(wide_cam ? VISION_STREAM_WIDE_ROAD : VISION_STREAM_ROAD);
} }
void OnroadWindow::paintEvent(QPaintEvent *event) { void OnroadWindow::paintEvent(QPaintEvent *event) {
@ -186,7 +186,7 @@ void OnroadHud::updateState(const UIState &s) {
maxspeed *= KM_TO_MILE; maxspeed *= KM_TO_MILE;
} }
QString maxspeed_str = cruise_set ? QString::number(std::nearbyint(maxspeed)) : "N/A"; QString maxspeed_str = cruise_set ? QString::number(std::nearbyint(maxspeed)) : "N/A";
float cur_speed = sm["carState"].getCarState().getVEgo() * (s.scene.is_metric ? MS_TO_KPH : MS_TO_MPH); float cur_speed = std::max(0.0, sm["carState"].getCarState().getVEgo() * (s.scene.is_metric ? MS_TO_KPH : MS_TO_MPH));
setProperty("is_cruise_set", cruise_set); setProperty("is_cruise_set", cruise_set);
setProperty("speed", QString::number(std::nearbyint(cur_speed))); setProperty("speed", QString::number(std::nearbyint(cur_speed)));

@ -17,10 +17,10 @@ const char frame_vertex_shader[] =
#else #else
"#version 300 es\n" "#version 300 es\n"
#endif #endif
"in vec4 aPosition;\n" "layout(location = 0) in vec4 aPosition;\n"
"in vec4 aTexCoord;\n" "layout(location = 1) in vec2 aTexCoord;\n"
"uniform mat4 uTransform;\n" "uniform mat4 uTransform;\n"
"out vec4 vTexCoord;\n" "out vec2 vTexCoord;\n"
"void main() {\n" "void main() {\n"
" gl_Position = uTransform * aPosition;\n" " gl_Position = uTransform * aPosition;\n"
" vTexCoord = aTexCoord;\n" " vTexCoord = aTexCoord;\n"
@ -33,11 +33,19 @@ const char frame_fragment_shader[] =
"#version 300 es\n" "#version 300 es\n"
"precision mediump float;\n" "precision mediump float;\n"
#endif #endif
"uniform sampler2D uTexture;\n" "uniform sampler2D uTextureY;\n"
"in vec4 vTexCoord;\n" "uniform sampler2D uTextureU;\n"
"uniform sampler2D uTextureV;\n"
"in vec2 vTexCoord;\n"
"out vec4 colorOut;\n" "out vec4 colorOut;\n"
"void main() {\n" "void main() {\n"
" colorOut = texture(uTexture, vTexCoord.xy);\n" " float y = texture(uTextureY, vTexCoord).r;\n"
" float u = texture(uTextureU, vTexCoord).r - 0.5;\n"
" float v = texture(uTextureV, vTexCoord).r - 0.5;\n"
" float r = y + 1.402 * v;\n"
" float g = y - 0.344 * u - 0.714 * v;\n"
" float b = y + 1.772 * u;\n"
" colorOut = vec4(r, g, b, 1.0);\n"
"}\n"; "}\n";
const mat4 device_transform = {{ const mat4 device_transform = {{
@ -94,6 +102,7 @@ CameraViewWidget::CameraViewWidget(std::string stream_name, VisionStreamType typ
stream_name(stream_name), stream_type(type), zoomed_view(zoom), QOpenGLWidget(parent) { stream_name(stream_name), stream_type(type), zoomed_view(zoom), QOpenGLWidget(parent) {
setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_OpaquePaintEvent);
connect(this, &CameraViewWidget::vipcThreadConnected, this, &CameraViewWidget::vipcConnected, Qt::BlockingQueuedConnection); connect(this, &CameraViewWidget::vipcThreadConnected, this, &CameraViewWidget::vipcConnected, Qt::BlockingQueuedConnection);
connect(this, &CameraViewWidget::vipcThreadFrameReceived, this, &CameraViewWidget::vipcFrameReceived);
} }
CameraViewWidget::~CameraViewWidget() { CameraViewWidget::~CameraViewWidget() {
@ -102,6 +111,7 @@ CameraViewWidget::~CameraViewWidget() {
glDeleteVertexArrays(1, &frame_vao); glDeleteVertexArrays(1, &frame_vao);
glDeleteBuffers(1, &frame_vbo); glDeleteBuffers(1, &frame_vbo);
glDeleteBuffers(1, &frame_ibo); glDeleteBuffers(1, &frame_ibo);
glDeleteBuffers(3, textures);
} }
doneCurrent(); doneCurrent();
} }
@ -119,7 +129,7 @@ void CameraViewWidget::initializeGL() {
GLint frame_pos_loc = program->attributeLocation("aPosition"); GLint frame_pos_loc = program->attributeLocation("aPosition");
GLint frame_texcoord_loc = program->attributeLocation("aTexCoord"); GLint frame_texcoord_loc = program->attributeLocation("aTexCoord");
auto [x1, x2, y1, y2] = stream_type == VISION_STREAM_RGB_DRIVER ? std::tuple(0.f, 1.f, 1.f, 0.f) : std::tuple(1.f, 0.f, 1.f, 0.f); auto [x1, x2, y1, y2] = stream_type == VISION_STREAM_DRIVER ? std::tuple(0.f, 1.f, 1.f, 0.f) : std::tuple(1.f, 0.f, 1.f, 0.f);
const uint8_t frame_indicies[] = {0, 1, 2, 0, 2, 3}; const uint8_t frame_indicies[] = {0, 1, 2, 0, 2, 3};
const float frame_coords[4][4] = { const float frame_coords[4][4] = {
{-1.0, -1.0, x2, y1}, // bl {-1.0, -1.0, x2, y1}, // bl
@ -144,10 +154,16 @@ void CameraViewWidget::initializeGL() {
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(frame_indicies), frame_indicies, GL_STATIC_DRAW); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(frame_indicies), frame_indicies, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0); glBindVertexArray(0);
glGenTextures(3, textures);
glUseProgram(program->programId());
glUniform1i(program->uniformLocation("uTextureY"), 0);
glUniform1i(program->uniformLocation("uTextureU"), 1);
glUniform1i(program->uniformLocation("uTextureV"), 2);
} }
void CameraViewWidget::showEvent(QShowEvent *event) { void CameraViewWidget::showEvent(QShowEvent *event) {
latest_texture_id = -1; latest_frame = nullptr;
if (!vipc_thread) { if (!vipc_thread) {
vipc_thread = new QThread(); vipc_thread = new QThread();
connect(vipc_thread, &QThread::started, [=]() { vipcThread(); }); connect(vipc_thread, &QThread::started, [=]() { vipcThread(); });
@ -167,12 +183,12 @@ void CameraViewWidget::hideEvent(QHideEvent *event) {
void CameraViewWidget::updateFrameMat(int w, int h) { void CameraViewWidget::updateFrameMat(int w, int h) {
if (zoomed_view) { if (zoomed_view) {
if (stream_type == VISION_STREAM_RGB_DRIVER) { if (stream_type == VISION_STREAM_DRIVER) {
frame_mat = matmul(device_transform, get_driver_view_transform(w, h, stream_width, stream_height)); frame_mat = matmul(device_transform, get_driver_view_transform(w, h, stream_width, stream_height));
} else { } else {
auto intrinsic_matrix = stream_type == VISION_STREAM_RGB_WIDE_ROAD ? ecam_intrinsic_matrix : fcam_intrinsic_matrix; auto intrinsic_matrix = stream_type == VISION_STREAM_WIDE_ROAD ? ecam_intrinsic_matrix : fcam_intrinsic_matrix;
float zoom = ZOOM / intrinsic_matrix.v[0]; float zoom = ZOOM / intrinsic_matrix.v[0];
if (stream_type == VISION_STREAM_RGB_WIDE_ROAD) { if (stream_type == VISION_STREAM_WIDE_ROAD) {
zoom *= 0.5; zoom *= 0.5;
} }
float zx = zoom * 2 * intrinsic_matrix.v[2] / width(); float zx = zoom * 2 * intrinsic_matrix.v[2] / width();
@ -200,7 +216,7 @@ void CameraViewWidget::paintGL() {
std::lock_guard lk(lock); std::lock_guard lk(lock);
if (latest_texture_id == -1) return; if (latest_frame == nullptr) return;
glViewport(0, 0, width(), height()); glViewport(0, 0, width(), height());
// sync with the PBO // sync with the PBO
@ -209,62 +225,59 @@ void CameraViewWidget::paintGL() {
} }
glBindVertexArray(frame_vao); glBindVertexArray(frame_vao);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture[latest_texture_id]->frame_tex);
glUseProgram(program->programId()); glUseProgram(program->programId());
glUniform1i(program->uniformLocation("uTexture"), 0); uint8_t *address[3] = {latest_frame->y, latest_frame->u, latest_frame->v};
glUniformMatrix4fv(program->uniformLocation("uTransform"), 1, GL_TRUE, frame_mat.v); for (int i = 0; i < 3; ++i) {
glActiveTexture(GL_TEXTURE0 + i);
glBindTexture(GL_TEXTURE_2D, textures[i]);
int width = i == 0 ? stream_width : stream_width / 2;
int height = i == 0 ? stream_height : stream_height / 2;
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, address[i]);
assert(glGetError() == GL_NO_ERROR);
}
glUniformMatrix4fv(program->uniformLocation("uTransform"), 1, GL_TRUE, frame_mat.v);
assert(glGetError() == GL_NO_ERROR); assert(glGetError() == GL_NO_ERROR);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, (const void *)0); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, (const void *)0);
glDisableVertexAttribArray(0); glDisableVertexAttribArray(0);
glBindVertexArray(0); glBindVertexArray(0);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
} }
void CameraViewWidget::vipcConnected(VisionIpcClient *vipc_client) { void CameraViewWidget::vipcConnected(VisionIpcClient *vipc_client) {
makeCurrent(); makeCurrent();
for (int i = 0; i < vipc_client->num_buffers; i++) { latest_frame = nullptr;
texture[i].reset(new EGLImageTexture(&vipc_client->buffers[i])); stream_width = vipc_client->buffers[0].width;
stream_height = vipc_client->buffers[0].height;
glBindTexture(GL_TEXTURE_2D, texture[i]->frame_tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
// BGR glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); for (int i = 0; i < 3; ++i) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_G, GL_GREEN); glBindTexture(GL_TEXTURE_2D, textures[i]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
int width = i == 0 ? stream_width : stream_width / 2;
int height = i == 0 ? stream_height : stream_height / 2;
glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, nullptr);
assert(glGetError() == GL_NO_ERROR); assert(glGetError() == GL_NO_ERROR);
} }
latest_texture_id = -1;
stream_width = vipc_client->buffers[0].width;
stream_height = vipc_client->buffers[0].height;
updateFrameMat(width(), height()); updateFrameMat(width(), height());
} }
void CameraViewWidget::vipcFrameReceived(VisionBuf *buf) {
latest_frame = buf;
update();
}
void CameraViewWidget::vipcThread() { void CameraViewWidget::vipcThread() {
VisionStreamType cur_stream_type = stream_type; VisionStreamType cur_stream_type = stream_type;
std::unique_ptr<VisionIpcClient> vipc_client; std::unique_ptr<VisionIpcClient> vipc_client;
std::unique_ptr<QOpenGLContext> ctx;
std::unique_ptr<QOffscreenSurface> surface;
std::unique_ptr<QOpenGLBuffer> gl_buffer;
ctx = std::make_unique<QOpenGLContext>();
ctx->setFormat(context()->format());
ctx->setShareContext(context());
ctx->create();
assert(ctx->isValid());
surface = std::make_unique<QOffscreenSurface>();
surface->setFormat(ctx->format());
surface->create();
ctx->makeCurrent(surface.get());
assert(QOpenGLContext::currentContext() == ctx.get());
initializeOpenGLFunctions();
while (!QThread::currentThread()->isInterruptionRequested()) { while (!QThread::currentThread()->isInterruptionRequested()) {
if (!vipc_client || cur_stream_type != stream_type) { if (!vipc_client || cur_stream_type != stream_type) {
cur_stream_type = stream_type; cur_stream_type = stream_type;
@ -276,48 +289,10 @@ void CameraViewWidget::vipcThread() {
QThread::msleep(100); QThread::msleep(100);
continue; continue;
} }
gl_buffer.reset(new QOpenGLBuffer(QOpenGLBuffer::PixelUnpackBuffer));
gl_buffer->create();
gl_buffer->bind();
gl_buffer->setUsagePattern(QOpenGLBuffer::StreamDraw);
gl_buffer->allocate(vipc_client->buffers[0].len);
emit vipcThreadConnected(vipc_client.get()); emit vipcThreadConnected(vipc_client.get());
} }
if (VisionBuf *buf = vipc_client->recv(nullptr, 1000)) { if (VisionBuf *buf = vipc_client->recv(nullptr, 1000)) {
{
std::lock_guard lk(lock);
void *texture_buffer = gl_buffer->map(QOpenGLBuffer::WriteOnly);
if (texture_buffer == nullptr) {
LOGE("gl_buffer->map returned nullptr");
continue;
}
memcpy(texture_buffer, buf->addr, buf->len);
gl_buffer->unmap();
// copy pixels from PBO to texture object
glBindTexture(GL_TEXTURE_2D, texture[buf->idx]->frame_tex);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, buf->width, buf->height, GL_RGB, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
assert(glGetError() == GL_NO_ERROR);
wait_fence.reset(new WaitFence());
// Ensure the fence is in the GPU command queue, or waiting on it might block
// https://www.khronos.org/opengl/wiki/Sync_Object#Flushing_and_contexts
glFlush();
latest_texture_id = buf->idx;
}
// Schedule update. update() will be invoked on the gui thread.
QMetaObject::invokeMethod(this, "update");
// TODO: remove later, it's only connected by DriverView.
emit vipcThreadFrameReceived(buf); emit vipcThreadFrameReceived(buf);
} }
} }

@ -8,7 +8,6 @@
#include <QThread> #include <QThread>
#include "cereal/visionipc/visionipc_client.h" #include "cereal/visionipc/visionipc_client.h"
#include "selfdrive/camerad/cameras/camera_common.h" #include "selfdrive/camerad/cameras/camera_common.h"
#include "selfdrive/common/visionimg.h"
#include "selfdrive/ui/ui.h" #include "selfdrive/ui/ui.h"
class CameraViewWidget : public QOpenGLWidget, protected QOpenGLFunctions { class CameraViewWidget : public QOpenGLWidget, protected QOpenGLFunctions {
@ -45,10 +44,9 @@ protected:
bool zoomed_view; bool zoomed_view;
std::mutex lock; std::mutex lock;
int latest_texture_id = -1; VisionBuf *latest_frame = nullptr;
GLuint frame_vao, frame_vbo, frame_ibo; GLuint frame_vao, frame_vbo, frame_ibo;
mat4 frame_mat; mat4 frame_mat;
std::unique_ptr<EGLImageTexture> texture[UI_BUF_COUNT];
std::unique_ptr<WaitFence> wait_fence; std::unique_ptr<WaitFence> wait_fence;
std::unique_ptr<QOpenGLShaderProgram> program; std::unique_ptr<QOpenGLShaderProgram> program;
QColor bg = QColor("#000000"); QColor bg = QColor("#000000");
@ -59,6 +57,9 @@ protected:
std::atomic<VisionStreamType> stream_type; std::atomic<VisionStreamType> stream_type;
QThread *vipc_thread = nullptr; QThread *vipc_thread = nullptr;
GLuint textures[3];
protected slots: protected slots:
void vipcConnected(VisionIpcClient *vipc_client); void vipcConnected(VisionIpcClient *vipc_client);
void vipcFrameReceived(VisionBuf *vipc_client);
}; };

@ -15,7 +15,6 @@ int main(int argc, char *argv[]) {
{"no-loop", REPLAY_FLAG_NO_LOOP, "stop at the end of the route"}, {"no-loop", REPLAY_FLAG_NO_LOOP, "stop at the end of the route"},
{"no-cache", REPLAY_FLAG_NO_FILE_CACHE, "turn off local cache"}, {"no-cache", REPLAY_FLAG_NO_FILE_CACHE, "turn off local cache"},
{"qcam", REPLAY_FLAG_QCAMERA, "load qcamera"}, {"qcam", REPLAY_FLAG_QCAMERA, "load qcamera"},
{"yuv", REPLAY_FLAG_SEND_YUV, "send yuv frame"},
{"no-hw-decoder", REPLAY_FLAG_NO_HW_DECODER, "disable HW video decoding"}, {"no-hw-decoder", REPLAY_FLAG_NO_HW_DECODER, "disable HW video decoding"},
{"no-vipc", REPLAY_FLAG_NO_VIPC, "do not output video"}, {"no-vipc", REPLAY_FLAG_NO_VIPC, "do not output video"},
}; };

@ -289,7 +289,7 @@ void Replay::startStream(const Segment *cur_segment) {
camera_size[type] = {fr->width, fr->height}; camera_size[type] = {fr->width, fr->height};
} }
} }
camera_server_ = std::make_unique<CameraServer>(camera_size, hasFlag(REPLAY_FLAG_SEND_YUV)); camera_server_ = std::make_unique<CameraServer>(camera_size, true);
} }
// start stream thread // start stream thread

@ -17,7 +17,6 @@ enum REPLAY_FLAGS {
REPLAY_FLAG_NO_LOOP = 0x0010, REPLAY_FLAG_NO_LOOP = 0x0010,
REPLAY_FLAG_NO_FILE_CACHE = 0x0020, REPLAY_FLAG_NO_FILE_CACHE = 0x0020,
REPLAY_FLAG_QCAMERA = 0x0040, REPLAY_FLAG_QCAMERA = 0x0040,
REPLAY_FLAG_SEND_YUV = 0x0080,
REPLAY_FLAG_NO_HW_DECODER = 0x0100, REPLAY_FLAG_NO_HW_DECODER = 0x0100,
REPLAY_FLAG_FULL_SPEED = 0x0200, REPLAY_FLAG_FULL_SPEED = 0x0200,
REPLAY_FLAG_NO_VIPC = 0x0400, REPLAY_FLAG_NO_VIPC = 0x0400,

@ -55,17 +55,33 @@ static void update_leads(UIState *s, const cereal::RadarState::Reader &radar_sta
} }
static void update_line_data(const UIState *s, const cereal::ModelDataV2::XYZTData::Reader &line, static void update_line_data(const UIState *s, const cereal::ModelDataV2::XYZTData::Reader &line,
float y_off, float z_off, line_vertices_data *pvd, int max_idx) { float y_off, float z_off, line_vertices_data *pvd, int max_idx, bool allow_invert=true) {
const auto line_x = line.getX(), line_y = line.getY(), line_z = line.getZ(); const auto line_x = line.getX(), line_y = line.getY(), line_z = line.getZ();
QPointF *v = &pvd->v[0];
std::vector<QPointF> left_points, right_points;
for (int i = 0; i <= max_idx; i++) { for (int i = 0; i <= max_idx; i++) {
v += calib_frame_to_full_frame(s, line_x[i], line_y[i] - y_off, line_z[i] + z_off, v); QPointF left, right;
bool l = calib_frame_to_full_frame(s, line_x[i], line_y[i] - y_off, line_z[i] + z_off, &left);
bool r = calib_frame_to_full_frame(s, line_x[i], line_y[i] + y_off, line_z[i] + z_off, &right);
if (l && r) {
// For wider lines the drawn polygon will "invert" when going over a hill and cause artifacts
if (!allow_invert && left_points.size() && left.y() > left_points.back().y()) {
continue;
}
left_points.push_back(left);
right_points.push_back(right);
} }
for (int i = max_idx; i >= 0; i--) {
v += calib_frame_to_full_frame(s, line_x[i], line_y[i] + y_off, line_z[i] + z_off, v);
} }
pvd->cnt = v - pvd->v;
pvd->cnt = 2 * left_points.size();
assert(left_points.size() == right_points.size());
assert(pvd->cnt <= std::size(pvd->v)); assert(pvd->cnt <= std::size(pvd->v));
for (int left_idx = 0; left_idx < left_points.size(); left_idx++){
int right_idx = 2 * left_points.size() - left_idx - 1;
pvd->v[left_idx] = left_points[left_idx];
pvd->v[right_idx] = right_points[left_idx];
}
} }
static void update_model(UIState *s, const cereal::ModelDataV2::Reader &model) { static void update_model(UIState *s, const cereal::ModelDataV2::Reader &model) {
@ -98,7 +114,7 @@ static void update_model(UIState *s, const cereal::ModelDataV2::Reader &model) {
max_distance = std::clamp((float)(lead_d - fmin(lead_d * 0.35, 10.)), 0.0f, max_distance); max_distance = std::clamp((float)(lead_d - fmin(lead_d * 0.35, 10.)), 0.0f, max_distance);
} }
max_idx = get_path_length_idx(model_position, max_distance); max_idx = get_path_length_idx(model_position, max_distance);
update_line_data(s, model_position, scene.end_to_end ? 0.9 : 0.5, 1.22, &scene.track_vertices, max_idx); update_line_data(s, model_position, scene.end_to_end ? 0.9 : 0.5, 1.22, &scene.track_vertices, max_idx, false);
} }
static void update_sockets(UIState *s) { static void update_sockets(UIState *s) {

@ -19,15 +19,16 @@ int main(int argc, char *argv[]) {
{ {
QHBoxLayout *hlayout = new QHBoxLayout(); QHBoxLayout *hlayout = new QHBoxLayout();
layout->addLayout(hlayout); layout->addLayout(hlayout);
hlayout->addWidget(new CameraViewWidget("navd", VISION_STREAM_RGB_MAP, false)); // TODO: make mapd output YUV
hlayout->addWidget(new CameraViewWidget("camerad", VISION_STREAM_RGB_ROAD, false)); // hlayout->addWidget(new CameraViewWidget("navd", VISION_STREAM_MAP, false));
hlayout->addWidget(new CameraViewWidget("camerad", VISION_STREAM_ROAD, false));
} }
{ {
QHBoxLayout *hlayout = new QHBoxLayout(); QHBoxLayout *hlayout = new QHBoxLayout();
layout->addLayout(hlayout); layout->addLayout(hlayout);
hlayout->addWidget(new CameraViewWidget("camerad", VISION_STREAM_RGB_DRIVER, false)); hlayout->addWidget(new CameraViewWidget("camerad", VISION_STREAM_DRIVER, false));
hlayout->addWidget(new CameraViewWidget("camerad", VISION_STREAM_RGB_WIDE_ROAD, false)); hlayout->addWidget(new CameraViewWidget("camerad", VISION_STREAM_WIDE_ROAD, false));
} }
return a.exec(); return a.exec();

@ -45,8 +45,6 @@ from selfdrive.version import is_tested_branch
LOCK_FILE = os.getenv("UPDATER_LOCK_FILE", "/tmp/safe_staging_overlay.lock") LOCK_FILE = os.getenv("UPDATER_LOCK_FILE", "/tmp/safe_staging_overlay.lock")
STAGING_ROOT = os.getenv("UPDATER_STAGING_ROOT", "/data/safe_staging") STAGING_ROOT = os.getenv("UPDATER_STAGING_ROOT", "/data/safe_staging")
NEOSUPDATE_DIR = os.getenv("UPDATER_NEOSUPDATE_DIR", "/data/neoupdate")
OVERLAY_UPPER = os.path.join(STAGING_ROOT, "upper") OVERLAY_UPPER = os.path.join(STAGING_ROOT, "upper")
OVERLAY_METADATA = os.path.join(STAGING_ROOT, "metadata") OVERLAY_METADATA = os.path.join(STAGING_ROOT, "metadata")
OVERLAY_MERGED = os.path.join(STAGING_ROOT, "merged") OVERLAY_MERGED = os.path.join(STAGING_ROOT, "merged")
@ -170,6 +168,8 @@ def setup_git_options(cwd: str) -> None:
("core.trustctime", "false"), ("core.trustctime", "false"),
("core.checkStat", "minimal"), ("core.checkStat", "minimal"),
("protocol.version", "2"), ("protocol.version", "2"),
("gc.auto", "0"),
("gc.autoDetach", "false"),
] ]
for option, value in git_cfg: for option, value in git_cfg:
run(["git", "config", option, value], cwd) run(["git", "config", option, value], cwd)
@ -178,10 +178,7 @@ def setup_git_options(cwd: str) -> None:
def dismount_overlay() -> None: def dismount_overlay() -> None:
if os.path.ismount(OVERLAY_MERGED): if os.path.ismount(OVERLAY_MERGED):
cloudlog.info("unmounting existing overlay") cloudlog.info("unmounting existing overlay")
args = ["umount", "-l", OVERLAY_MERGED] run(["sudo", "umount", "-l", OVERLAY_MERGED])
if TICI:
args = ["sudo"] + args
run(args)
def init_overlay() -> None: def init_overlay() -> None:
@ -204,7 +201,6 @@ def init_overlay() -> None:
params.put_bool("UpdateAvailable", False) params.put_bool("UpdateAvailable", False)
set_consistent_flag(False) set_consistent_flag(False)
dismount_overlay() dismount_overlay()
if TICI:
run(["sudo", "rm", "-rf", STAGING_ROOT]) run(["sudo", "rm", "-rf", STAGING_ROOT])
if os.path.isdir(STAGING_ROOT): if os.path.isdir(STAGING_ROOT):
shutil.rmtree(STAGING_ROOT) shutil.rmtree(STAGING_ROOT)
@ -229,18 +225,15 @@ def init_overlay() -> None:
overlay_opts = f"lowerdir={BASEDIR},upperdir={OVERLAY_UPPER},workdir={OVERLAY_METADATA}" overlay_opts = f"lowerdir={BASEDIR},upperdir={OVERLAY_UPPER},workdir={OVERLAY_METADATA}"
mount_cmd = ["mount", "-t", "overlay", "-o", overlay_opts, "none", OVERLAY_MERGED] mount_cmd = ["mount", "-t", "overlay", "-o", overlay_opts, "none", OVERLAY_MERGED]
if TICI:
run(["sudo"] + mount_cmd) run(["sudo"] + mount_cmd)
run(["sudo", "chmod", "755", os.path.join(OVERLAY_METADATA, "work")]) run(["sudo", "chmod", "755", os.path.join(OVERLAY_METADATA, "work")])
else:
run(mount_cmd)
git_diff = run(["git", "diff"], OVERLAY_MERGED, low_priority=True) git_diff = run(["git", "diff"], OVERLAY_MERGED, low_priority=True)
params.put("GitDiff", git_diff) params.put("GitDiff", git_diff)
cloudlog.info(f"git diff output:\n{git_diff}") cloudlog.info(f"git diff output:\n{git_diff}")
def finalize_update() -> None: def finalize_update(wait_helper: WaitTimeHelper) -> None:
"""Take the current OverlayFS merged view and finalize a copy outside of """Take the current OverlayFS merged view and finalize a copy outside of
OverlayFS, ready to be swapped-in at BASEDIR. Copy using shutil.copytree""" OverlayFS, ready to be swapped-in at BASEDIR. Copy using shutil.copytree"""
@ -256,6 +249,17 @@ def finalize_update() -> None:
run(["git", "reset", "--hard"], FINALIZED) run(["git", "reset", "--hard"], FINALIZED)
run(["git", "submodule", "foreach", "--recursive", "git", "reset"], FINALIZED) run(["git", "submodule", "foreach", "--recursive", "git", "reset"], FINALIZED)
cloudlog.info("Starting git gc")
t = time.monotonic()
try:
run(["git", "gc"], FINALIZED)
cloudlog.event("Done git gc", duration=time.monotonic() - t)
except subprocess.CalledProcessError:
cloudlog.exception(f"Failed git gc, took {time.monotonic() - t:.3f} s")
if wait_helper.shutdown:
cloudlog.info("got interrupted finalizing overlay")
else:
set_consistent_flag(True) set_consistent_flag(True)
cloudlog.info("done finalizing overlay") cloudlog.info("done finalizing overlay")
@ -328,7 +332,7 @@ def fetch_update(wait_helper: WaitTimeHelper) -> bool:
handle_agnos_update(wait_helper) handle_agnos_update(wait_helper)
# Create the finalized, ready-to-swap update # Create the finalized, ready-to-swap update
finalize_update() finalize_update(wait_helper)
cloudlog.info("openpilot update successful!") cloudlog.info("openpilot update successful!")
else: else:
cloudlog.info("nothing new from git at this time") cloudlog.info("nothing new from git at this time")
@ -365,32 +369,13 @@ def main() -> None:
overlay_init = Path(os.path.join(BASEDIR, ".overlay_init")) overlay_init = Path(os.path.join(BASEDIR, ".overlay_init"))
overlay_init.unlink(missing_ok=True) overlay_init.unlink(missing_ok=True)
first_run = True update_failed_count = 0 # TODO: Load from param?
last_fetch_time = 0.0
update_failed_count = 0
# Set initial params for offroad alerts
set_params(False, 0, None)
# Wait for IsOffroad to be set before our first update attempt
wait_helper = WaitTimeHelper(proc) wait_helper = WaitTimeHelper(proc)
wait_helper.sleep(30)
# Run the update loop # Run the update loop
# * every 5m, do a lightweight internet/update check
# * every 10m, do a full git fetch
while not wait_helper.shutdown: while not wait_helper.shutdown:
update_now = wait_helper.ready_event.is_set()
wait_helper.ready_event.clear() wait_helper.ready_event.clear()
# Don't run updater while onroad or if the time's wrong
time_wrong = datetime.datetime.utcnow().year < 2019
is_onroad = not params.get_bool("IsOffroad")
if is_onroad or time_wrong:
wait_helper.sleep(30)
cloudlog.info("not running updater, not offroad")
continue
# Attempt an update # Attempt an update
exception = None exception = None
new_version = False new_version = False
@ -398,19 +383,16 @@ def main() -> None:
try: try:
init_overlay() init_overlay()
# TODO: still needed? skip this and just fetch?
# Lightweight internt check
internet_ok, update_available = check_for_update() internet_ok, update_available = check_for_update()
if internet_ok and not update_available: if internet_ok and not update_available:
update_failed_count = 0 update_failed_count = 0
# Fetch updates at most every 10 minutes # Fetch update
if internet_ok and (update_now or time.monotonic() - last_fetch_time > 60*10): if internet_ok:
new_version = fetch_update(wait_helper) new_version = fetch_update(wait_helper)
update_failed_count = 0 update_failed_count = 0
last_fetch_time = time.monotonic()
if first_run and not new_version and os.path.isdir(NEOSUPDATE_DIR):
shutil.rmtree(NEOSUPDATE_DIR)
first_run = False
except subprocess.CalledProcessError as e: except subprocess.CalledProcessError as e:
cloudlog.event( cloudlog.event(
"update process failed", "update process failed",
@ -425,13 +407,14 @@ def main() -> None:
exception = str(e) exception = str(e)
overlay_init.unlink(missing_ok=True) overlay_init.unlink(missing_ok=True)
if not wait_helper.shutdown:
try: try:
set_params(new_version, update_failed_count, exception) set_params(new_version, update_failed_count, exception)
except Exception: except Exception:
cloudlog.exception("uncaught updated exception while setting params, shouldn't happen") cloudlog.exception("uncaught updated exception while setting params, shouldn't happen")
# TODO: replace this with a good backoff # infrequent attempts if we successfully updated recently
wait_helper.sleep(300) wait_helper.sleep(5*60 if update_failed_count > 0 else 90*60)
dismount_overlay() dismount_overlay()

@ -1,274 +0,0 @@
BoringSSL is a fork of OpenSSL. As such, large parts of it fall under OpenSSL
licensing. Files that are completely new have a Google copyright and an ISC
license. This license is reproduced at the bottom of this file.
Contributors to BoringSSL are required to follow the CLA rules for Chromium:
https://cla.developers.google.com/clas
Files in third_party/ have their own licenses, as described therein. The MIT
license, for third_party/fiat, which, unlike other third_party directories, is
compiled into non-test libraries, is included below.
The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the
OpenSSL License and the original SSLeay license apply to the toolkit. See below
for the actual license texts. Actually both licenses are BSD-style Open Source
licenses. In case of any license issues related to OpenSSL please contact
openssl-core@openssl.org.
The following are Google-internal bug numbers where explicit permission from
some authors is recorded for use of their work. (This is purely for our own
record keeping.)
27287199
27287880
27287883
OpenSSL License
---------------
/* ====================================================================
* Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
Original SSLeay License
-----------------------
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
ISC license used for completely new code in BoringSSL:
/* Copyright (c) 2015, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
The code in third_party/fiat carries the MIT license:
Copyright (c) 2015-2016 the fiat-crypto authors (see
https://github.com/mit-plv/fiat-crypto/blob/master/AUTHORS).
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
The code in third_party/sike also carries the MIT license:
Copyright (c) Microsoft Corporation. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE
Licenses for support code
-------------------------
Parts of the TLS test suite are under the Go license. This code is not included
in BoringSSL (i.e. libcrypto and libssl) when compiled, however, so
distributing code linked against BoringSSL does not trigger this license:
Copyright (c) 2009 The Go Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
BoringSSL uses the Chromium test infrastructure to run a continuous build,
trybots etc. The scripts which manage this, and the script for generating build
metadata, are under the Chromium license. Distributing code linked against
BoringSSL does not trigger this license.
Copyright 2015 The Chromium Authors. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

@ -1,192 +0,0 @@
BoringSSL is a fork of OpenSSL. As such, large parts of it fall under OpenSSL
licensing. Files that are completely new have a Google copyright and an ISC
license. This license is reproduced at the bottom of this file.
Contributors to BoringSSL are required to follow the CLA rules for Chromium:
https://cla.developers.google.com/clas
Some files from Intel are under yet another license, which is also included
underneath.
The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the
OpenSSL License and the original SSLeay license apply to the toolkit. See below
for the actual license texts. Actually both licenses are BSD-style Open Source
licenses. In case of any license issues related to OpenSSL please contact
openssl-core@openssl.org.
The following are Google-internal bug numbers where explicit permission from
some authors is recorded for use of their work. (This is purely for our own
record keeping.)
27287199
27287880
27287883
OpenSSL License
---------------
/* ====================================================================
* Copyright (c) 1998-2011 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
Original SSLeay License
-----------------------
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
ISC license used for completely new code in BoringSSL:
/* Copyright (c) 2015, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
Some files from Intel carry the following license:
# Copyright (c) 2012, Intel Corporation
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the
# distribution.
#
# * Neither the name of the Intel Corporation nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
#
# THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

@ -1,7 +0,0 @@
# with neos tree
cd ~/android/system
mka libcrypt_static libssl_static
cp ~/android/system/out/target/product/oneplus3/obj/STATIC_LIBRARIES/libcrypto_static_intermediates/libcrypto_static.a lib/
cp ~/android/system/out/target/product/oneplus3/obj/STATIC_LIBRARIES/libssl_static_intermediates/libssl_static.a lib/

@ -1,315 +0,0 @@
/* Copyright (c) 2014, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#ifndef OPENSSL_HEADER_AEAD_H
#define OPENSSL_HEADER_AEAD_H
#include <openssl/base.h>
#if defined(__cplusplus)
extern "C" {
#endif
/* Authenticated Encryption with Additional Data.
*
* AEAD couples confidentiality and integrity in a single primtive. AEAD
* algorithms take a key and then can seal and open individual messages. Each
* message has a unique, per-message nonce and, optionally, additional data
* which is authenticated but not included in the ciphertext.
*
* The |EVP_AEAD_CTX_init| function initialises an |EVP_AEAD_CTX| structure and
* performs any precomputation needed to use |aead| with |key|. The length of
* the key, |key_len|, is given in bytes.
*
* The |tag_len| argument contains the length of the tags, in bytes, and allows
* for the processing of truncated authenticators. A zero value indicates that
* the default tag length should be used and this is defined as
* |EVP_AEAD_DEFAULT_TAG_LENGTH| in order to make the code clear. Using
* truncated tags increases an attacker's chance of creating a valid forgery.
* Be aware that the attacker's chance may increase more than exponentially as
* would naively be expected.
*
* When no longer needed, the initialised |EVP_AEAD_CTX| structure must be
* passed to |EVP_AEAD_CTX_cleanup|, which will deallocate any memory used.
*
* With an |EVP_AEAD_CTX| in hand, one can seal and open messages. These
* operations are intended to meet the standard notions of privacy and
* authenticity for authenticated encryption. For formal definitions see
* Bellare and Namprempre, "Authenticated encryption: relations among notions
* and analysis of the generic composition paradigm," Lecture Notes in Computer
* Science B<1976> (2000), 531545,
* http://www-cse.ucsd.edu/~mihir/papers/oem.html.
*
* When sealing messages, a nonce must be given. The length of the nonce is
* fixed by the AEAD in use and is returned by |EVP_AEAD_nonce_length|. *The
* nonce must be unique for all messages with the same key*. This is critically
* important - nonce reuse may completely undermine the security of the AEAD.
* Nonces may be predictable and public, so long as they are unique. Uniqueness
* may be achieved with a simple counter or, if large enough, may be generated
* randomly. The nonce must be passed into the "open" operation by the receiver
* so must either be implicit (e.g. a counter), or must be transmitted along
* with the sealed message.
*
* The "seal" and "open" operations are atomic - an entire message must be
* encrypted or decrypted in a single call. Large messages may have to be split
* up in order to accomodate this. When doing so, be mindful of the need not to
* repeat nonces and the possibility that an attacker could duplicate, reorder
* or drop message chunks. For example, using a single key for a given (large)
* message and sealing chunks with nonces counting from zero would be secure as
* long as the number of chunks was securely transmitted. (Otherwise an
* attacker could truncate the message by dropping chunks from the end.)
*
* The number of chunks could be transmitted by prefixing it to the plaintext,
* for example. This also assumes that no other message would ever use the same
* key otherwise the rule that nonces must be unique for a given key would be
* violated.
*
* The "seal" and "open" operations also permit additional data to be
* authenticated via the |ad| parameter. This data is not included in the
* ciphertext and must be identical for both the "seal" and "open" call. This
* permits implicit context to be authenticated but may be empty if not needed.
*
* The "seal" and "open" operations may work in-place if the |out| and |in|
* arguments are equal. They may also be used to shift the data left inside the
* same buffer if |out| is less than |in|. However, |out| may not point inside
* the input data otherwise the input may be overwritten before it has been
* read. This situation will cause an error.
*
* The "seal" and "open" operations return one on success and zero on error. */
/* AEAD algorithms. */
/* EVP_aead_aes_128_gcm is AES-128 in Galois Counter Mode. */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm(void);
/* EVP_aead_aes_256_gcm is AES-256 in Galois Counter Mode. */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm(void);
/* EVP_aead_chacha20_poly1305 is an AEAD built from ChaCha20 and Poly1305. */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305(void);
/* EVP_aead_aes_128_key_wrap is AES-128 Key Wrap mode. This should never be
* used except to interoperate with existing systems that use this mode.
*
* If the nonce is empty then the default nonce will be used, otherwise it must
* be eight bytes long. The input must be a multiple of eight bytes long. No
* additional data can be given to this mode. */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_key_wrap(void);
/* EVP_aead_aes_256_key_wrap is AES-256 in Key Wrap mode. This should never be
* used except to interoperate with existing systems that use this mode.
*
* See |EVP_aead_aes_128_key_wrap| for details. */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_key_wrap(void);
/* EVP_aead_aes_128_ctr_hmac_sha256 is AES-128 in CTR mode with HMAC-SHA256 for
* authentication. The nonce is 12 bytes; the bottom 32-bits are used as the
* block counter, thus the maximum plaintext size is 64GB. */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ctr_hmac_sha256(void);
/* EVP_aead_aes_128_ctr_hmac_sha256 is AES-256 in CTR mode with HMAC-SHA256 for
* authentication. See |EVP_aead_aes_128_ctr_hmac_sha256| for details. */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_ctr_hmac_sha256(void);
/* EVP_has_aes_hardware returns one if we enable hardware support for fast and
* constant-time AES-GCM. */
OPENSSL_EXPORT int EVP_has_aes_hardware(void);
/* TLS-specific AEAD algorithms.
*
* These AEAD primitives do not meet the definition of generic AEADs. They are
* all specific to TLS and should not be used outside of that context. They must
* be initialized with |EVP_AEAD_CTX_init_with_direction|, are stateful, and may
* not be used concurrently. Any nonces are used as IVs, so they must be
* unpredictable. They only accept an |ad| parameter of length 11 (the standard
* TLS one with length omitted). */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_md5_tls(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_sha1_tls(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha256_tls(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls_implicit_iv(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha256_tls(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha384_tls(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(void);
/* SSLv3-specific AEAD algorithms.
*
* These AEAD primitives do not meet the definition of generic AEADs. They are
* all specific to SSLv3 and should not be used outside of that context. They
* must be initialized with |EVP_AEAD_CTX_init_with_direction|, are stateful,
* and may not be used concurrently. They only accept an |ad| parameter of
* length 9 (the standard TLS one with length and version omitted). */
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_md5_ssl3(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_sha1_ssl3(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_ssl3(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_ssl3(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_ssl3(void);
/* Utility functions. */
/* EVP_AEAD_key_length returns the length, in bytes, of the keys used by
* |aead|. */
OPENSSL_EXPORT size_t EVP_AEAD_key_length(const EVP_AEAD *aead);
/* EVP_AEAD_nonce_length returns the length, in bytes, of the per-message nonce
* for |aead|. */
OPENSSL_EXPORT size_t EVP_AEAD_nonce_length(const EVP_AEAD *aead);
/* EVP_AEAD_max_overhead returns the maximum number of additional bytes added
* by the act of sealing data with |aead|. */
OPENSSL_EXPORT size_t EVP_AEAD_max_overhead(const EVP_AEAD *aead);
/* EVP_AEAD_max_tag_len returns the maximum tag length when using |aead|. This
* is the largest value that can be passed as |tag_len| to
* |EVP_AEAD_CTX_init|. */
OPENSSL_EXPORT size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead);
/* AEAD operations. */
/* An EVP_AEAD_CTX represents an AEAD algorithm configured with a specific key
* and message-independent IV. */
typedef struct evp_aead_ctx_st {
const EVP_AEAD *aead;
/* aead_state is an opaque pointer to whatever state the AEAD needs to
* maintain. */
void *aead_state;
} EVP_AEAD_CTX;
/* EVP_AEAD_MAX_KEY_LENGTH contains the maximum key length used by
* any AEAD defined in this header. */
#define EVP_AEAD_MAX_KEY_LENGTH 80
/* EVP_AEAD_MAX_NONCE_LENGTH contains the maximum nonce length used by
* any AEAD defined in this header. */
#define EVP_AEAD_MAX_NONCE_LENGTH 16
/* EVP_AEAD_MAX_OVERHEAD contains the maximum overhead used by any AEAD
* defined in this header. */
#define EVP_AEAD_MAX_OVERHEAD 64
/* EVP_AEAD_DEFAULT_TAG_LENGTH is a magic value that can be passed to
* EVP_AEAD_CTX_init to indicate that the default tag length for an AEAD should
* be used. */
#define EVP_AEAD_DEFAULT_TAG_LENGTH 0
/* evp_aead_direction_t denotes the direction of an AEAD operation. */
enum evp_aead_direction_t {
evp_aead_open,
evp_aead_seal,
};
/* EVP_AEAD_CTX_init initializes |ctx| for the given AEAD algorithm from |impl|.
* The |impl| argument may be NULL to choose the default implementation.
* Authentication tags may be truncated by passing a size as |tag_len|. A
* |tag_len| of zero indicates the default tag length and this is defined as
* EVP_AEAD_DEFAULT_TAG_LENGTH for readability.
*
* Returns 1 on success. Otherwise returns 0 and pushes to the error stack. In
* the error case, you do not need to call |EVP_AEAD_CTX_cleanup|, but it's
* harmless to do so. */
OPENSSL_EXPORT int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
const uint8_t *key, size_t key_len,
size_t tag_len, ENGINE *impl);
/* EVP_AEAD_CTX_init_with_direction calls |EVP_AEAD_CTX_init| for normal
* AEADs. For TLS-specific and SSL3-specific AEADs, it initializes |ctx| for a
* given direction. */
OPENSSL_EXPORT int EVP_AEAD_CTX_init_with_direction(
EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, const uint8_t *key, size_t key_len,
size_t tag_len, enum evp_aead_direction_t dir);
/* EVP_AEAD_CTX_cleanup frees any data allocated by |ctx|. It is a no-op to
* call |EVP_AEAD_CTX_cleanup| on a |EVP_AEAD_CTX| that has been |memset| to
* all zeros. */
OPENSSL_EXPORT void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx);
/* EVP_AEAD_CTX_seal encrypts and authenticates |in_len| bytes from |in| and
* authenticates |ad_len| bytes from |ad| and writes the result to |out|. It
* returns one on success and zero otherwise.
*
* This function may be called (with the same |EVP_AEAD_CTX|) concurrently with
* itself or |EVP_AEAD_CTX_open|.
*
* At most |max_out_len| bytes are written to |out| and, in order to ensure
* success, |max_out_len| should be |in_len| plus the result of
* |EVP_AEAD_max_overhead|. On successful return, |*out_len| is set to the
* actual number of bytes written.
*
* The length of |nonce|, |nonce_len|, must be equal to the result of
* |EVP_AEAD_nonce_length| for this AEAD.
*
* |EVP_AEAD_CTX_seal| never results in a partial output. If |max_out_len| is
* insufficient, zero will be returned. (In this case, |*out_len| is set to
* zero.)
*
* If |in| and |out| alias then |out| must be <= |in|. */
OPENSSL_EXPORT int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
size_t *out_len, size_t max_out_len,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len);
/* EVP_AEAD_CTX_open authenticates |in_len| bytes from |in| and |ad_len| bytes
* from |ad| and decrypts at most |in_len| bytes into |out|. It returns one on
* success and zero otherwise.
*
* This function may be called (with the same |EVP_AEAD_CTX|) concurrently with
* itself or |EVP_AEAD_CTX_seal|.
*
* At most |in_len| bytes are written to |out|. In order to ensure success,
* |max_out_len| should be at least |in_len|. On successful return, |*out_len|
* is set to the the actual number of bytes written.
*
* The length of |nonce|, |nonce_len|, must be equal to the result of
* |EVP_AEAD_nonce_length| for this AEAD.
*
* |EVP_AEAD_CTX_open| never results in a partial output. If |max_out_len| is
* insufficient, zero will be returned. (In this case, |*out_len| is set to
* zero.)
*
* If |in| and |out| alias then |out| must be <= |in|. */
OPENSSL_EXPORT int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
size_t *out_len, size_t max_out_len,
const uint8_t *nonce, size_t nonce_len,
const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len);
/* Obscure functions. */
/* EVP_AEAD_CTX_get_rc4_state sets |*out_key| to point to an RC4 key structure.
* It returns one on success or zero if |ctx| doesn't have an RC4 key. */
OPENSSL_EXPORT int EVP_AEAD_CTX_get_rc4_state(const EVP_AEAD_CTX *ctx,
const RC4_KEY **out_key);
#if defined(__cplusplus)
} /* extern C */
#endif
#endif /* OPENSSL_HEADER_AEAD_H */

@ -1,158 +0,0 @@
/* ====================================================================
* Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ==================================================================== */
#ifndef OPENSSL_HEADER_AES_H
#define OPENSSL_HEADER_AES_H
#include <openssl/base.h>
#if defined(__cplusplus)
extern "C" {
#endif
/* Raw AES functions. */
#define AES_ENCRYPT 1
#define AES_DECRYPT 0
/* AES_MAXNR is the maximum number of AES rounds. */
#define AES_MAXNR 14
#define AES_BLOCK_SIZE 16
/* aes_key_st should be an opaque type, but EVP requires that the size be
* known. */
struct aes_key_st {
uint32_t rd_key[4 * (AES_MAXNR + 1)];
unsigned rounds;
};
typedef struct aes_key_st AES_KEY;
/* AES_set_encrypt_key configures |aeskey| to encrypt with the |bits|-bit key,
* |key|.
*
* WARNING: unlike other OpenSSL functions, this returns zero on success and a
* negative number on error. */
OPENSSL_EXPORT int AES_set_encrypt_key(const uint8_t *key, unsigned bits,
AES_KEY *aeskey);
/* AES_set_decrypt_key configures |aeskey| to decrypt with the |bits|-bit key,
* |key|.
*
* WARNING: unlike other OpenSSL functions, this returns zero on success and a
* negative number on error. */
OPENSSL_EXPORT int AES_set_decrypt_key(const uint8_t *key, unsigned bits,
AES_KEY *aeskey);
/* AES_encrypt encrypts a single block from |in| to |out| with |key|. The |in|
* and |out| pointers may overlap. */
OPENSSL_EXPORT void AES_encrypt(const uint8_t *in, uint8_t *out,
const AES_KEY *key);
/* AES_decrypt decrypts a single block from |in| to |out| with |key|. The |in|
* and |out| pointers may overlap. */
OPENSSL_EXPORT void AES_decrypt(const uint8_t *in, uint8_t *out,
const AES_KEY *key);
/* Block cipher modes. */
/* AES_ctr128_encrypt encrypts (or decrypts, it's the same in CTR mode) |len|
* bytes from |in| to |out|. The |num| parameter must be set to zero on the
* first call and |ivec| will be incremented. */
OPENSSL_EXPORT void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out,
size_t len, const AES_KEY *key,
uint8_t ivec[AES_BLOCK_SIZE],
uint8_t ecount_buf[AES_BLOCK_SIZE],
unsigned int *num);
/* AES_ecb_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) a single,
* 16 byte block from |in| to |out|. */
OPENSSL_EXPORT void AES_ecb_encrypt(const uint8_t *in, uint8_t *out,
const AES_KEY *key, const int enc);
/* AES_cbc_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) |len|
* bytes from |in| to |out|. The length must be a multiple of the block size. */
OPENSSL_EXPORT void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
const AES_KEY *key, uint8_t *ivec,
const int enc);
/* AES_ofb128_encrypt encrypts (or decrypts, it's the same in CTR mode) |len|
* bytes from |in| to |out|. The |num| parameter must be set to zero on the
* first call. */
OPENSSL_EXPORT void AES_ofb128_encrypt(const uint8_t *in, uint8_t *out,
size_t len, const AES_KEY *key,
uint8_t *ivec, int *num);
/* AES_cfb128_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) |len|
* bytes from |in| to |out|. The |num| parameter must be set to zero on the
* first call. */
OPENSSL_EXPORT void AES_cfb128_encrypt(const uint8_t *in, uint8_t *out,
size_t len, const AES_KEY *key,
uint8_t *ivec, int *num, int enc);
/* Android compatibility section.
*
* These functions are declared, temporarily, for Android because
* wpa_supplicant will take a little time to sync with upstream. Outside of
* Android they'll have no definition. */
OPENSSL_EXPORT int AES_wrap_key(AES_KEY *key, const uint8_t *iv, uint8_t *out,
const uint8_t *in, unsigned in_len);
OPENSSL_EXPORT int AES_unwrap_key(AES_KEY *key, const uint8_t *iv, uint8_t *out,
const uint8_t *in, unsigned in_len);
#if defined(__cplusplus)
} /* extern C */
#endif
#endif /* OPENSSL_HEADER_AES_H */

File diff suppressed because it is too large Load Diff

@ -1,76 +0,0 @@
/* crypto/asn1/asn1_mac.h */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#ifndef HEADER_ASN1_MAC_H
#define HEADER_ASN1_MAC_H
#include <openssl/asn1.h>
#ifdef __cplusplus
extern "C" {
#endif
OPENSSL_EXPORT int asn1_GetSequence(ASN1_const_CTX *c, long *length);
#ifdef __cplusplus
}
#endif
#endif

@ -1,907 +0,0 @@
/* asn1t.h */
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
* project 2000.
*/
/* ====================================================================
* Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
#ifndef HEADER_ASN1T_H
#define HEADER_ASN1T_H
#include <openssl/base.h>
#include <openssl/asn1.h>
#ifdef OPENSSL_BUILD_SHLIBCRYPTO
# undef OPENSSL_EXTERN
# define OPENSSL_EXTERN OPENSSL_EXPORT
#endif
/* ASN1 template defines, structures and functions */
#ifdef __cplusplus
extern "C" {
#endif
/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */
#define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr))
/* Macros for start and end of ASN1_ITEM definition */
#define ASN1_ITEM_start(itname) \
const ASN1_ITEM itname##_it = {
#define ASN1_ITEM_end(itname) \
};
/* Macros to aid ASN1 template writing */
#define ASN1_ITEM_TEMPLATE(tname) \
static const ASN1_TEMPLATE tname##_item_tt
#define ASN1_ITEM_TEMPLATE_END(tname) \
;\
ASN1_ITEM_start(tname) \
ASN1_ITYPE_PRIMITIVE,\
-1,\
&tname##_item_tt,\
0,\
NULL,\
0,\
#tname \
ASN1_ITEM_end(tname)
/* This is a ASN1 type which just embeds a template */
/* This pair helps declare a SEQUENCE. We can do:
*
* ASN1_SEQUENCE(stname) = {
* ... SEQUENCE components ...
* } ASN1_SEQUENCE_END(stname)
*
* This will produce an ASN1_ITEM called stname_it
* for a structure called stname.
*
* If you want the same structure but a different
* name then use:
*
* ASN1_SEQUENCE(itname) = {
* ... SEQUENCE components ...
* } ASN1_SEQUENCE_END_name(stname, itname)
*
* This will create an item called itname_it using
* a structure called stname.
*/
#define ASN1_SEQUENCE(tname) \
static const ASN1_TEMPLATE tname##_seq_tt[]
#define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname)
#define ASN1_SEQUENCE_END_name(stname, tname) \
;\
ASN1_ITEM_start(tname) \
ASN1_ITYPE_SEQUENCE,\
V_ASN1_SEQUENCE,\
tname##_seq_tt,\
sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
NULL,\
sizeof(stname),\
#stname \
ASN1_ITEM_end(tname)
#define ASN1_NDEF_SEQUENCE(tname) \
ASN1_SEQUENCE(tname)
#define ASN1_NDEF_SEQUENCE_cb(tname, cb) \
ASN1_SEQUENCE_cb(tname, cb)
#define ASN1_SEQUENCE_cb(tname, cb) \
static const ASN1_AUX tname##_aux = {NULL, 0, 0, cb, 0}; \
ASN1_SEQUENCE(tname)
#define ASN1_BROKEN_SEQUENCE(tname) \
static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0}; \
ASN1_SEQUENCE(tname)
#define ASN1_SEQUENCE_ref(tname, cb) \
static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), cb, 0}; \
ASN1_SEQUENCE(tname)
#define ASN1_SEQUENCE_enc(tname, enc, cb) \
static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, cb, offsetof(tname, enc)}; \
ASN1_SEQUENCE(tname)
#define ASN1_NDEF_SEQUENCE_END(tname) \
;\
ASN1_ITEM_start(tname) \
ASN1_ITYPE_NDEF_SEQUENCE,\
V_ASN1_SEQUENCE,\
tname##_seq_tt,\
sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
NULL,\
sizeof(tname),\
#tname \
ASN1_ITEM_end(tname)
#define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname)
#define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
#define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname)
#define ASN1_SEQUENCE_END_ref(stname, tname) \
;\
ASN1_ITEM_start(tname) \
ASN1_ITYPE_SEQUENCE,\
V_ASN1_SEQUENCE,\
tname##_seq_tt,\
sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
&tname##_aux,\
sizeof(stname),\
#stname \
ASN1_ITEM_end(tname)
#define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \
;\
ASN1_ITEM_start(tname) \
ASN1_ITYPE_NDEF_SEQUENCE,\
V_ASN1_SEQUENCE,\
tname##_seq_tt,\
sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\
&tname##_aux,\
sizeof(stname),\
#stname \
ASN1_ITEM_end(tname)
/* This pair helps declare a CHOICE type. We can do:
*
* ASN1_CHOICE(chname) = {
* ... CHOICE options ...
* ASN1_CHOICE_END(chname)
*
* This will produce an ASN1_ITEM called chname_it
* for a structure called chname. The structure
* definition must look like this:
* typedef struct {
* int type;
* union {
* ASN1_SOMETHING *opt1;
* ASN1_SOMEOTHER *opt2;
* } value;
* } chname;
*
* the name of the selector must be 'type'.
* to use an alternative selector name use the
* ASN1_CHOICE_END_selector() version.
*/
#define ASN1_CHOICE(tname) \
static const ASN1_TEMPLATE tname##_ch_tt[]
#define ASN1_CHOICE_cb(tname, cb) \
static const ASN1_AUX tname##_aux = {NULL, 0, 0, cb, 0}; \
ASN1_CHOICE(tname)
#define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname)
#define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type)
#define ASN1_CHOICE_END_selector(stname, tname, selname) \
;\
ASN1_ITEM_start(tname) \
ASN1_ITYPE_CHOICE,\
offsetof(stname,selname) ,\
tname##_ch_tt,\
sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
NULL,\
sizeof(stname),\
#stname \
ASN1_ITEM_end(tname)
#define ASN1_CHOICE_END_cb(stname, tname, selname) \
;\
ASN1_ITEM_start(tname) \
ASN1_ITYPE_CHOICE,\
offsetof(stname,selname) ,\
tname##_ch_tt,\
sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\
&tname##_aux,\
sizeof(stname),\
#stname \
ASN1_ITEM_end(tname)
/* This helps with the template wrapper form of ASN1_ITEM */
#define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \
(flags), (tag), 0,\
#name, ASN1_ITEM_ref(type) }
/* These help with SEQUENCE or CHOICE components */
/* used to declare other types */
#define ASN1_EX_TYPE(flags, tag, stname, field, type) { \
(flags), (tag), offsetof(stname, field),\
#field, ASN1_ITEM_ref(type) }
/* used when the structure is combined with the parent */
#define ASN1_EX_COMBINE(flags, tag, type) { \
(flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) }
/* implicit and explicit helper macros */
#define ASN1_IMP_EX(stname, field, type, tag, ex) \
ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type)
#define ASN1_EXP_EX(stname, field, type, tag, ex) \
ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type)
/* Any defined by macros: the field used is in the table itself */
#define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
#define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) }
/* Plain simple type */
#define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type)
/* OPTIONAL simple type */
#define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type)
/* IMPLICIT tagged simple type */
#define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0)
/* IMPLICIT tagged OPTIONAL simple type */
#define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
/* Same as above but EXPLICIT */
#define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0)
#define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL)
/* SEQUENCE OF type */
#define ASN1_SEQUENCE_OF(stname, field, type) \
ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type)
/* OPTIONAL SEQUENCE OF */
#define ASN1_SEQUENCE_OF_OPT(stname, field, type) \
ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
/* Same as above but for SET OF */
#define ASN1_SET_OF(stname, field, type) \
ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type)
#define ASN1_SET_OF_OPT(stname, field, type) \
ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type)
/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */
#define ASN1_IMP_SET_OF(stname, field, type, tag) \
ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
#define ASN1_EXP_SET_OF(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF)
#define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \
ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
#define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL)
#define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \
ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
#define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \
ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
#define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF)
#define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL)
/* EXPLICIT using indefinite length constructed form */
#define ASN1_NDEF_EXP(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF)
/* EXPLICIT OPTIONAL using indefinite length constructed form */
#define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \
ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF)
/* Macros for the ASN1_ADB structure */
#define ASN1_ADB(name) \
static const ASN1_ADB_TABLE name##_adbtbl[]
#define ASN1_ADB_END(name, flags, field, app_table, def, none) \
;\
static const ASN1_ADB name##_adb = {\
flags,\
offsetof(name, field),\
app_table,\
name##_adbtbl,\
sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\
def,\
none\
}
#define ADB_ENTRY(val, template) {val, template}
#define ASN1_ADB_TEMPLATE(name) \
static const ASN1_TEMPLATE name##_tt
/* This is the ASN1 template structure that defines
* a wrapper round the actual type. It determines the
* actual position of the field in the value structure,
* various flags such as OPTIONAL and the field name.
*/
struct ASN1_TEMPLATE_st {
unsigned long flags; /* Various flags */
long tag; /* tag, not used if no tagging */
unsigned long offset; /* Offset of this field in structure */
#ifndef NO_ASN1_FIELD_NAMES
const char *field_name; /* Field name */
#endif
ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */
};
/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */
#define ASN1_TEMPLATE_item(t) (t->item_ptr)
#define ASN1_TEMPLATE_adb(t) (t->item_ptr)
typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE;
typedef struct ASN1_ADB_st ASN1_ADB;
struct ASN1_ADB_st {
unsigned long flags; /* Various flags */
unsigned long offset; /* Offset of selector field */
STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */
const ASN1_ADB_TABLE *tbl; /* Table of possible types */
long tblcount; /* Number of entries in tbl */
const ASN1_TEMPLATE *default_tt; /* Type to use if no match */
const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */
};
struct ASN1_ADB_TABLE_st {
long value; /* NID for an object or value for an int */
const ASN1_TEMPLATE tt; /* item for this value */
};
/* template flags */
/* Field is optional */
#define ASN1_TFLG_OPTIONAL (0x1)
/* Field is a SET OF */
#define ASN1_TFLG_SET_OF (0x1 << 1)
/* Field is a SEQUENCE OF */
#define ASN1_TFLG_SEQUENCE_OF (0x2 << 1)
/* Special case: this refers to a SET OF that
* will be sorted into DER order when encoded *and*
* the corresponding STACK will be modified to match
* the new order.
*/
#define ASN1_TFLG_SET_ORDER (0x3 << 1)
/* Mask for SET OF or SEQUENCE OF */
#define ASN1_TFLG_SK_MASK (0x3 << 1)
/* These flags mean the tag should be taken from the
* tag field. If EXPLICIT then the underlying type
* is used for the inner tag.
*/
/* IMPLICIT tagging */
#define ASN1_TFLG_IMPTAG (0x1 << 3)
/* EXPLICIT tagging, inner tag from underlying type */
#define ASN1_TFLG_EXPTAG (0x2 << 3)
#define ASN1_TFLG_TAG_MASK (0x3 << 3)
/* context specific IMPLICIT */
#define ASN1_TFLG_IMPLICIT ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT
/* context specific EXPLICIT */
#define ASN1_TFLG_EXPLICIT ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT
/* If tagging is in force these determine the
* type of tag to use. Otherwise the tag is
* determined by the underlying type. These
* values reflect the actual octet format.
*/
/* Universal tag */
#define ASN1_TFLG_UNIVERSAL (0x0<<6)
/* Application tag */
#define ASN1_TFLG_APPLICATION (0x1<<6)
/* Context specific tag */
#define ASN1_TFLG_CONTEXT (0x2<<6)
/* Private tag */
#define ASN1_TFLG_PRIVATE (0x3<<6)
#define ASN1_TFLG_TAG_CLASS (0x3<<6)
/* These are for ANY DEFINED BY type. In this case
* the 'item' field points to an ASN1_ADB structure
* which contains a table of values to decode the
* relevant type
*/
#define ASN1_TFLG_ADB_MASK (0x3<<8)
#define ASN1_TFLG_ADB_OID (0x1<<8)
#define ASN1_TFLG_ADB_INT (0x1<<9)
/* This flag means a parent structure is passed
* instead of the field: this is useful is a
* SEQUENCE is being combined with a CHOICE for
* example. Since this means the structure and
* item name will differ we need to use the
* ASN1_CHOICE_END_name() macro for example.
*/
#define ASN1_TFLG_COMBINE (0x1<<10)
/* This flag when present in a SEQUENCE OF, SET OF
* or EXPLICIT causes indefinite length constructed
* encoding to be used if required.
*/
#define ASN1_TFLG_NDEF (0x1<<11)
/* This is the actual ASN1 item itself */
struct ASN1_ITEM_st {
char itype; /* The item type, primitive, SEQUENCE, CHOICE or extern */
long utype; /* underlying type */
const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains the contents */
long tcount; /* Number of templates if SEQUENCE or CHOICE */
const void *funcs; /* functions that handle this type */
long size; /* Structure size (usually)*/
#ifndef NO_ASN1_FIELD_NAMES
const char *sname; /* Structure name */
#endif
};
/* These are values for the itype field and
* determine how the type is interpreted.
*
* For PRIMITIVE types the underlying type
* determines the behaviour if items is NULL.
*
* Otherwise templates must contain a single
* template and the type is treated in the
* same way as the type specified in the template.
*
* For SEQUENCE types the templates field points
* to the members, the size field is the
* structure size.
*
* For CHOICE types the templates field points
* to each possible member (typically a union)
* and the 'size' field is the offset of the
* selector.
*
* The 'funcs' field is used for application
* specific functions.
*
* For COMPAT types the funcs field gives a
* set of functions that handle this type, this
* supports the old d2i, i2d convention.
*
* The EXTERN type uses a new style d2i/i2d.
* The new style should be used where possible
* because it avoids things like the d2i IMPLICIT
* hack.
*
* MSTRING is a multiple string type, it is used
* for a CHOICE of character strings where the
* actual strings all occupy an ASN1_STRING
* structure. In this case the 'utype' field
* has a special meaning, it is used as a mask
* of acceptable types using the B_ASN1 constants.
*
* NDEF_SEQUENCE is the same as SEQUENCE except
* that it will use indefinite length constructed
* encoding if requested.
*
*/
#define ASN1_ITYPE_PRIMITIVE 0x0
#define ASN1_ITYPE_SEQUENCE 0x1
#define ASN1_ITYPE_CHOICE 0x2
#define ASN1_ITYPE_COMPAT 0x3
#define ASN1_ITYPE_EXTERN 0x4
#define ASN1_ITYPE_MSTRING 0x5
#define ASN1_ITYPE_NDEF_SEQUENCE 0x6
/* Cache for ASN1 tag and length, so we
* don't keep re-reading it for things
* like CHOICE
*/
struct ASN1_TLC_st{
char valid; /* Values below are valid */
int ret; /* return value */
long plen; /* length */
int ptag; /* class value */
int pclass; /* class value */
int hdrlen; /* header length */
};
/* Typedefs for ASN1 function pointers */
typedef ASN1_VALUE * ASN1_new_func(void);
typedef void ASN1_free_func(ASN1_VALUE *a);
typedef ASN1_VALUE * ASN1_d2i_func(ASN1_VALUE **a, const unsigned char ** in, long length);
typedef int ASN1_i2d_func(ASN1_VALUE * a, unsigned char **in);
typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it,
int tag, int aclass, char opt, ASN1_TLC *ctx);
typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it);
typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval,
int indent, const char *fname,
const ASN1_PCTX *pctx);
typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
typedef struct ASN1_COMPAT_FUNCS_st {
ASN1_new_func *asn1_new;
ASN1_free_func *asn1_free;
ASN1_d2i_func *asn1_d2i;
ASN1_i2d_func *asn1_i2d;
} ASN1_COMPAT_FUNCS;
typedef struct ASN1_EXTERN_FUNCS_st {
void *app_data;
ASN1_ex_new_func *asn1_ex_new;
ASN1_ex_free_func *asn1_ex_free;
ASN1_ex_free_func *asn1_ex_clear;
ASN1_ex_d2i *asn1_ex_d2i;
ASN1_ex_i2d *asn1_ex_i2d;
ASN1_ex_print_func *asn1_ex_print;
} ASN1_EXTERN_FUNCS;
typedef struct ASN1_PRIMITIVE_FUNCS_st {
void *app_data;
unsigned long flags;
ASN1_ex_new_func *prim_new;
ASN1_ex_free_func *prim_free;
ASN1_ex_free_func *prim_clear;
ASN1_primitive_c2i *prim_c2i;
ASN1_primitive_i2c *prim_i2c;
ASN1_primitive_print *prim_print;
} ASN1_PRIMITIVE_FUNCS;
/* This is the ASN1_AUX structure: it handles various
* miscellaneous requirements. For example the use of
* reference counts and an informational callback.
*
* The "informational callback" is called at various
* points during the ASN1 encoding and decoding. It can
* be used to provide minor customisation of the structures
* used. This is most useful where the supplied routines
* *almost* do the right thing but need some extra help
* at a few points. If the callback returns zero then
* it is assumed a fatal error has occurred and the
* main operation should be abandoned.
*
* If major changes in the default behaviour are required
* then an external type is more appropriate.
*/
typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it,
void *exarg);
typedef struct ASN1_AUX_st {
void *app_data;
int flags;
int ref_offset; /* Offset of reference value */
ASN1_aux_cb *asn1_cb;
int enc_offset; /* Offset of ASN1_ENCODING structure */
} ASN1_AUX;
/* For print related callbacks exarg points to this structure */
typedef struct ASN1_PRINT_ARG_st {
BIO *out;
int indent;
const ASN1_PCTX *pctx;
} ASN1_PRINT_ARG;
/* For streaming related callbacks exarg points to this structure */
typedef struct ASN1_STREAM_ARG_st {
/* BIO to stream through */
BIO *out;
/* BIO with filters appended */
BIO *ndef_bio;
/* Streaming I/O boundary */
unsigned char **boundary;
} ASN1_STREAM_ARG;
/* Flags in ASN1_AUX */
/* Use a reference count */
#define ASN1_AFLG_REFCOUNT 1
/* Save the encoding of structure (useful for signatures) */
#define ASN1_AFLG_ENCODING 2
/* The Sequence length is invalid */
#define ASN1_AFLG_BROKEN 4
/* operation values for asn1_cb */
#define ASN1_OP_NEW_PRE 0
#define ASN1_OP_NEW_POST 1
#define ASN1_OP_FREE_PRE 2
#define ASN1_OP_FREE_POST 3
#define ASN1_OP_D2I_PRE 4
#define ASN1_OP_D2I_POST 5
#define ASN1_OP_I2D_PRE 6
#define ASN1_OP_I2D_POST 7
#define ASN1_OP_PRINT_PRE 8
#define ASN1_OP_PRINT_POST 9
#define ASN1_OP_STREAM_PRE 10
#define ASN1_OP_STREAM_POST 11
#define ASN1_OP_DETACHED_PRE 12
#define ASN1_OP_DETACHED_POST 13
/* Macro to implement a primitive type */
#define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0)
#define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \
ASN1_ITEM_start(itname) \
ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \
ASN1_ITEM_end(itname)
/* Macro to implement a multi string type */
#define IMPLEMENT_ASN1_MSTRING(itname, mask) \
ASN1_ITEM_start(itname) \
ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \
ASN1_ITEM_end(itname)
/* Macro to implement an ASN1_ITEM in terms of old style funcs */
#define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE)
#define IMPLEMENT_COMPAT_ASN1_type(sname, tag) \
static const ASN1_COMPAT_FUNCS sname##_ff = { \
(ASN1_new_func *)sname##_new, \
(ASN1_free_func *)sname##_free, \
(ASN1_d2i_func *)d2i_##sname, \
(ASN1_i2d_func *)i2d_##sname, \
}; \
ASN1_ITEM_start(sname) \
ASN1_ITYPE_COMPAT, \
tag, \
NULL, \
0, \
&sname##_ff, \
0, \
#sname \
ASN1_ITEM_end(sname)
#define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \
ASN1_ITEM_start(sname) \
ASN1_ITYPE_EXTERN, \
tag, \
NULL, \
0, \
&fptrs, \
0, \
#sname \
ASN1_ITEM_end(sname)
/* Macro to implement standard functions in terms of ASN1_ITEM structures */
#define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname)
#define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname)
#define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \
IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname)
#define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \
IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname)
#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \
IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname)
#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \
pre stname *fname##_new(void) \
{ \
return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
} \
pre void fname##_free(stname *a) \
{ \
ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
}
#define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \
stname *fname##_new(void) \
{ \
return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \
} \
void fname##_free(stname *a) \
{ \
ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \
}
#define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \
stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
{ \
return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
} \
int i2d_##fname(stname *a, unsigned char **out) \
{ \
return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
}
#define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \
int i2d_##stname##_NDEF(stname *a, unsigned char **out) \
{ \
return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\
}
/* This includes evil casts to remove const: they will go away when full
* ASN1 constification is done.
*/
#define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
stname *d2i_##fname(stname **a, const unsigned char **in, long len) \
{ \
return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\
} \
int i2d_##fname(const stname *a, unsigned char **out) \
{ \
return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\
}
#define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \
stname * stname##_dup(stname *x) \
{ \
return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \
}
#define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \
IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname)
#define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \
int fname##_print_ctx(BIO *out, stname *x, int indent, \
const ASN1_PCTX *pctx) \
{ \
return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \
ASN1_ITEM_rptr(itname), pctx); \
}
#define IMPLEMENT_ASN1_FUNCTIONS_const(name) \
IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name)
#define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \
IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname)
/* external definitions for primitive types */
DECLARE_ASN1_ITEM(ASN1_BOOLEAN)
DECLARE_ASN1_ITEM(ASN1_TBOOLEAN)
DECLARE_ASN1_ITEM(ASN1_FBOOLEAN)
DECLARE_ASN1_ITEM(ASN1_SEQUENCE)
DECLARE_ASN1_ITEM(CBIGNUM)
DECLARE_ASN1_ITEM(BIGNUM)
DECLARE_ASN1_ITEM(LONG)
DECLARE_ASN1_ITEM(ZLONG)
DECLARE_STACK_OF(ASN1_VALUE)
/* Functions used internally by the ASN1 code */
int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt);
int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it,
int tag, int aclass, char opt, ASN1_TLC *ctx);
int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass);
int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_TEMPLATE *tt);
void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it);
int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it);
ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr);
void asn1_refcount_set_one(ASN1_VALUE **pval, const ASN1_ITEM *it);
int asn1_refcount_dec_and_test_zero(ASN1_VALUE **pval, const ASN1_ITEM *it);
void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, const ASN1_ITEM *it);
int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, const ASN1_ITEM *it);
#ifdef __cplusplus
}
#endif
#endif

@ -1,233 +0,0 @@
/* ====================================================================
* Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
#ifndef OPENSSL_HEADER_BASE_H
#define OPENSSL_HEADER_BASE_H
/* This file should be the first included by all BoringSSL headers. */
#include <stddef.h>
#include <stdint.h>
#include <sys/types.h>
#include <openssl/opensslfeatures.h>
#if defined(__cplusplus)
extern "C" {
#endif
#if defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64)
#define OPENSSL_64_BIT
#define OPENSSL_X86_64
#elif defined(__x86) || defined(__i386) || defined(__i386__) || defined(_M_IX86)
#define OPENSSL_32_BIT
#define OPENSSL_X86
#elif defined(__aarch64__)
#define OPENSSL_64_BIT
#define OPENSSL_AARCH64
#elif defined(__arm) || defined(__arm__) || defined(_M_ARM)
#define OPENSSL_32_BIT
#define OPENSSL_ARM
#elif defined(__aarch64__)
#define OPENSSL_64_BIT
#define OPENSSL_AARCH64
#elif defined(__mips__) && !defined(__LP64__)
#define OPENSSL_32_BIT
#define OPENSSL_MIPS
#elif defined(__mips__) && defined(__LP64__)
#define OPENSSL_64_BIT
#define OPENSSL_MIPS64
#elif defined(__pnacl__)
#define OPENSSL_32_BIT
#define OPENSSL_PNACL
#else
#error "Unknown target CPU"
#endif
#if defined(__APPLE__)
#define OPENSSL_APPLE
#endif
#if defined(WIN32) || defined(_WIN32)
#define OPENSSL_WINDOWS
#endif
#if defined(TRUSTY)
#define OPENSSL_TRUSTY
#define OPENSSL_NO_THREADS
#endif
#define OPENSSL_IS_BORINGSSL
#define OPENSSL_VERSION_NUMBER 0x10002000
#if defined(BORINGSSL_SHARED_LIBRARY)
#if defined(OPENSSL_WINDOWS)
#if defined(BORINGSSL_IMPLEMENTATION)
#define OPENSSL_EXPORT __declspec(dllexport)
#else
#define OPENSSL_EXPORT __declspec(dllimport)
#endif
#else /* defined(OPENSSL_WINDOWS) */
#if defined(BORINGSSL_IMPLEMENTATION)
#define OPENSSL_EXPORT __attribute__((visibility("default")))
#else
#define OPENSSL_EXPORT
#endif
#endif /* defined(OPENSSL_WINDOWS) */
#else /* defined(BORINGSSL_SHARED_LIBRARY) */
#define OPENSSL_EXPORT
#endif /* defined(BORINGSSL_SHARED_LIBRARY) */
/* CRYPTO_THREADID is a dummy value. */
typedef int CRYPTO_THREADID;
typedef int ASN1_BOOLEAN;
typedef int ASN1_NULL;
typedef struct ASN1_ITEM_st ASN1_ITEM;
typedef struct asn1_object_st ASN1_OBJECT;
typedef struct asn1_pctx_st ASN1_PCTX;
typedef struct asn1_string_st ASN1_BIT_STRING;
typedef struct asn1_string_st ASN1_BMPSTRING;
typedef struct asn1_string_st ASN1_ENUMERATED;
typedef struct asn1_string_st ASN1_GENERALIZEDTIME;
typedef struct asn1_string_st ASN1_GENERALSTRING;
typedef struct asn1_string_st ASN1_IA5STRING;
typedef struct asn1_string_st ASN1_INTEGER;
typedef struct asn1_string_st ASN1_OCTET_STRING;
typedef struct asn1_string_st ASN1_PRINTABLESTRING;
typedef struct asn1_string_st ASN1_STRING;
typedef struct asn1_string_st ASN1_T61STRING;
typedef struct asn1_string_st ASN1_TIME;
typedef struct asn1_string_st ASN1_UNIVERSALSTRING;
typedef struct asn1_string_st ASN1_UTCTIME;
typedef struct asn1_string_st ASN1_UTF8STRING;
typedef struct asn1_string_st ASN1_VISIBLESTRING;
typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID;
typedef struct DIST_POINT_st DIST_POINT;
typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT;
typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS;
typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE;
typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL;
typedef struct X509_POLICY_NODE_st X509_POLICY_NODE;
typedef struct X509_POLICY_TREE_st X509_POLICY_TREE;
typedef struct X509_algor_st X509_ALGOR;
typedef struct X509_crl_st X509_CRL;
typedef struct X509_pubkey_st X509_PUBKEY;
typedef struct bignum_ctx BN_CTX;
typedef struct bignum_st BIGNUM;
typedef struct bio_method_st BIO_METHOD;
typedef struct bio_st BIO;
typedef struct bn_gencb_st BN_GENCB;
typedef struct bn_mont_ctx_st BN_MONT_CTX;
typedef struct buf_mem_st BUF_MEM;
typedef struct cbb_st CBB;
typedef struct cbs_st CBS;
typedef struct cmac_ctx_st CMAC_CTX;
typedef struct conf_st CONF;
typedef struct conf_value_st CONF_VALUE;
typedef struct dh_method DH_METHOD;
typedef struct dh_st DH;
typedef struct dsa_method DSA_METHOD;
typedef struct dsa_st DSA;
typedef struct ec_key_st EC_KEY;
typedef struct ecdsa_method_st ECDSA_METHOD;
typedef struct ecdsa_sig_st ECDSA_SIG;
typedef struct engine_st ENGINE;
typedef struct env_md_ctx_st EVP_MD_CTX;
typedef struct env_md_st EVP_MD;
typedef struct evp_aead_st EVP_AEAD;
typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX;
typedef struct evp_cipher_st EVP_CIPHER;
typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD;
typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
typedef struct evp_pkey_method_st EVP_PKEY_METHOD;
typedef struct evp_pkey_st EVP_PKEY;
typedef struct hmac_ctx_st HMAC_CTX;
typedef struct md4_state_st MD4_CTX;
typedef struct md5_state_st MD5_CTX;
typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO;
typedef struct pkcs12_st PKCS12;
typedef struct rand_meth_st RAND_METHOD;
typedef struct rc4_key_st RC4_KEY;
typedef struct rsa_meth_st RSA_METHOD;
typedef struct rsa_st RSA;
typedef struct sha256_state_st SHA256_CTX;
typedef struct sha512_state_st SHA512_CTX;
typedef struct sha_state_st SHA_CTX;
typedef struct ssl_ctx_st SSL_CTX;
typedef struct ssl_st SSL;
typedef struct st_ERR_FNS ERR_FNS;
typedef struct v3_ext_ctx X509V3_CTX;
typedef struct x509_crl_method_st X509_CRL_METHOD;
typedef struct x509_revoked_st X509_REVOKED;
typedef struct x509_st X509;
typedef struct x509_store_ctx_st X509_STORE_CTX;
typedef struct x509_store_st X509_STORE;
typedef void *OPENSSL_BLOCK;
#if defined(__cplusplus)
} /* extern C */
#endif
#endif /* OPENSSL_HEADER_BASE_H */

@ -1,179 +0,0 @@
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
#ifndef OPENSSL_HEADER_BASE64_H
#define OPENSSL_HEADER_BASE64_H
#include <openssl/base.h>
#if defined(__cplusplus)
extern "C" {
#endif
/* base64 functions.
*
* For historical reasons, these functions have the EVP_ prefix but just do
* base64 encoding and decoding. */
typedef struct evp_encode_ctx_st EVP_ENCODE_CTX;
/* Encoding */
/* EVP_EncodeInit initialises |*ctx|, which is typically stack
* allocated, for an encoding operation.
*
* NOTE: The encoding operation breaks its output with newlines every
* 64 characters of output (48 characters of input). Use
* EVP_EncodeBlock to encode raw base64. */
OPENSSL_EXPORT void EVP_EncodeInit(EVP_ENCODE_CTX *ctx);
/* EVP_EncodeUpdate encodes |in_len| bytes from |in| and writes an encoded
* version of them to |out| and sets |*out_len| to the number of bytes written.
* Some state may be contained in |ctx| so |EVP_EncodeFinal| must be used to
* flush it before using the encoded data. */
OPENSSL_EXPORT void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out,
int *out_len, const uint8_t *in,
size_t in_len);
/* EVP_EncodeFinal flushes any remaining output bytes from |ctx| to |out| and
* sets |*out_len| to the number of bytes written. */
OPENSSL_EXPORT void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out,
int *out_len);
/* EVP_EncodeBlock encodes |src_len| bytes from |src| and writes the
* result to |dst| with a trailing NUL. It returns the number of bytes
* written, not including this trailing NUL. */
OPENSSL_EXPORT size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src,
size_t src_len);
/* EVP_EncodedLength sets |*out_len| to the number of bytes that will be needed
* to call |EVP_EncodeBlock| on an input of length |len|. This includes the
* final NUL that |EVP_EncodeBlock| writes. It returns one on success or zero
* on error. */
OPENSSL_EXPORT int EVP_EncodedLength(size_t *out_len, size_t len);
/* Decoding */
/* EVP_DecodedLength sets |*out_len| to the maximum number of bytes
* that will be needed to call |EVP_DecodeBase64| on an input of
* length |len|. */
OPENSSL_EXPORT int EVP_DecodedLength(size_t *out_len, size_t len);
/* EVP_DecodeBase64 decodes |in_len| bytes from base64 and writes
* |*out_len| bytes to |out|. |max_out| is the size of the output
* buffer. If it is not enough for the maximum output size, the
* operation fails. */
OPENSSL_EXPORT int EVP_DecodeBase64(uint8_t *out, size_t *out_len,
size_t max_out, const uint8_t *in,
size_t in_len);
/* EVP_DecodeInit initialises |*ctx|, which is typically stack allocated, for
* a decoding operation.
*
* TODO(davidben): This isn't a straight-up base64 decode either. Document
* and/or fix exactly what's going on here; maximum line length and such. */
OPENSSL_EXPORT void EVP_DecodeInit(EVP_ENCODE_CTX *ctx);
/* EVP_DecodeUpdate decodes |in_len| bytes from |in| and writes the decoded
* data to |out| and sets |*out_len| to the number of bytes written. Some state
* may be contained in |ctx| so |EVP_DecodeFinal| must be used to flush it
* before using the encoded data.
*
* It returns -1 on error, one if a full line of input was processed and zero
* if the line was short (i.e. it was the last line). */
OPENSSL_EXPORT int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out,
int *out_len, const uint8_t *in,
size_t in_len);
/* EVP_DecodeFinal flushes any remaining output bytes from |ctx| to |out| and
* sets |*out_len| to the number of bytes written. It returns one on success
* and minus one on error. */
OPENSSL_EXPORT int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out,
int *out_len);
/* Deprecated: EVP_DecodeBlock encodes |src_len| bytes from |src| and
* writes the result to |dst|. It returns the number of bytes written
* or -1 on error.
*
* WARNING: EVP_DecodeBlock's return value does not take padding into
* account. It also strips leading whitespace and trailing
* whitespace. */
OPENSSL_EXPORT int EVP_DecodeBlock(uint8_t *dst, const uint8_t *src,
size_t src_len);
struct evp_encode_ctx_st {
unsigned num; /* number saved in a partial encode/decode */
unsigned length; /* The length is either the output line length
* (in input bytes) or the shortest input line
* length that is ok. Once decoding begins,
* the length is adjusted up each time a longer
* line is decoded */
uint8_t enc_data[80]; /* data to encode */
unsigned line_num; /* number read on current line */
int expect_nl;
};
#if defined(__cplusplus)
} /* extern C */
#endif
#endif /* OPENSSL_HEADER_BASE64_H */

@ -1,910 +0,0 @@
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
#ifndef OPENSSL_HEADER_BIO_H
#define OPENSSL_HEADER_BIO_H
#include <openssl/base.h>
#include <stdio.h> /* For FILE */
#include <openssl/err.h> /* for ERR_print_errors_fp */
#include <openssl/ex_data.h>
#include <openssl/stack.h>
#include <openssl/thread.h>
#if defined(__cplusplus)
extern "C" {
#endif
/* BIO abstracts over a file-descriptor like interface. */
/* Allocation and freeing. */
DEFINE_STACK_OF(BIO);
/* BIO_new creates a new BIO with the given type and a reference count of one.
* It returns the fresh |BIO|, or NULL on error. */
OPENSSL_EXPORT BIO *BIO_new(const BIO_METHOD *type);
/* BIO_free decrements the reference count of |bio|. If the reference count
* drops to zero, it (optionally) calls the BIO's callback with |BIO_CB_FREE|,
* frees the ex_data and then, if the BIO has a destroy callback for the
* method, calls it. Finally it frees |bio| itself. It then repeats that for
* the next BIO in the chain, if any.
*
* It returns one on success or zero otherwise. */
OPENSSL_EXPORT int BIO_free(BIO *bio);
/* BIO_vfree performs the same actions as |BIO_free|, but has a void return
* value. This is provided for API-compat.
*
* TODO(fork): remove. */
OPENSSL_EXPORT void BIO_vfree(BIO *bio);
/* BIO_up_ref increments the reference count of |bio| and returns it. */
OPENSSL_EXPORT BIO *BIO_up_ref(BIO *bio);
/* Basic I/O. */
/* BIO_read attempts to read |len| bytes into |data|. It returns the number of
* bytes read, zero on EOF, or a negative number on error. */
OPENSSL_EXPORT int BIO_read(BIO *bio, void *data, int len);
/* BIO_gets "reads a line" from |bio| and puts at most |size| bytes into |buf|.
* It returns the number of bytes read or a negative number on error. The
* phrase "reads a line" is in quotes in the previous sentence because the
* exact operation depends on the BIO's method. For example, a digest BIO will
* return the digest in response to a |BIO_gets| call.
*
* TODO(fork): audit the set of BIOs that we end up needing. If all actually
* return a line for this call, remove the warning above. */
OPENSSL_EXPORT int BIO_gets(BIO *bio, char *buf, int size);
/* BIO_write writes |len| bytes from |data| to BIO. It returns the number of
* bytes written or a negative number on error. */
OPENSSL_EXPORT int BIO_write(BIO *bio, const void *data, int len);
/* BIO_puts writes a NUL terminated string from |buf| to |bio|. It returns the
* number of bytes written or a negative number on error. */
OPENSSL_EXPORT int BIO_puts(BIO *bio, const char *buf);
/* BIO_flush flushes any buffered output. It returns one on success and zero
* otherwise. */
OPENSSL_EXPORT int BIO_flush(BIO *bio);
/* Low-level control functions.
*
* These are generic functions for sending control requests to a BIO. In
* general one should use the wrapper functions like |BIO_get_close|. */
/* BIO_ctrl sends the control request |cmd| to |bio|. The |cmd| argument should
* be one of the |BIO_C_*| values. */
OPENSSL_EXPORT long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg);
/* BIO_ptr_ctrl acts like |BIO_ctrl| but passes the address of a |void*|
* pointer as |parg| and returns the value that is written to it, or NULL if
* the control request returns <= 0. */
OPENSSL_EXPORT char *BIO_ptr_ctrl(BIO *bp, int cmd, long larg);
/* BIO_int_ctrl acts like |BIO_ctrl| but passes the address of a copy of |iarg|
* as |parg|. */
OPENSSL_EXPORT long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg);
/* BIO_reset resets |bio| to its initial state, the precise meaning of which
* depends on the concrete type of |bio|. It returns one on success and zero
* otherwise. */
OPENSSL_EXPORT int BIO_reset(BIO *bio);
/* BIO_set_flags ORs |flags| with |bio->flags|. */
OPENSSL_EXPORT void BIO_set_flags(BIO *bio, int flags);
/* BIO_test_flags returns |bio->flags| AND |flags|. */
OPENSSL_EXPORT int BIO_test_flags(const BIO *bio, int flags);
/* BIO_should_read returns non-zero if |bio| encountered a temporary error
* while reading (i.e. EAGAIN), indicating that the caller should retry the
* read. */
OPENSSL_EXPORT int BIO_should_read(const BIO *bio);
/* BIO_should_write returns non-zero if |bio| encountered a temporary error
* while writing (i.e. EAGAIN), indicating that the caller should retry the
* write. */
OPENSSL_EXPORT int BIO_should_write(const BIO *bio);
/* BIO_should_retry returns non-zero if the reason that caused a failed I/O
* operation is temporary and thus the operation should be retried. Otherwise,
* it was a permanent error and it returns zero. */
OPENSSL_EXPORT int BIO_should_retry(const BIO *bio);
/* BIO_should_io_special returns non-zero if |bio| encountered a temporary
* error while performing a special I/O operation, indicating that the caller
* should retry. The operation that caused the error is returned by
* |BIO_get_retry_reason|. */
OPENSSL_EXPORT int BIO_should_io_special(const BIO *bio);
/* BIO_RR_SSL_X509_LOOKUP indicates that an SSL BIO blocked because the SSL
* library returned with SSL_ERROR_WANT_X509_LOOKUP.
*
* TODO(fork): remove. */
#define BIO_RR_SSL_X509_LOOKUP 0x01
/* BIO_RR_CONNECT indicates that a connect would have blocked */
#define BIO_RR_CONNECT 0x02
/* BIO_RR_ACCEPT indicates that an accept would have blocked */
#define BIO_RR_ACCEPT 0x03
/* BIO_RR_SSL_CHANNEL_ID_LOOKUP indicates that the ChannelID code cannot find
* a private key for a TLS connection. */
#define BIO_RR_SSL_CHANNEL_ID_LOOKUP 0x04
/* BIO_get_retry_reason returns the special I/O operation that needs to be
* retried. The return value is one of the |BIO_RR_*| values. */
OPENSSL_EXPORT int BIO_get_retry_reason(const BIO *bio);
/* BIO_clear_flags ANDs |bio->flags| with the bitwise-complement of |flags|. */
OPENSSL_EXPORT void BIO_clear_flags(BIO *bio, int flags);
/* BIO_set_retry_read sets the |BIO_FLAGS_READ| and |BIO_FLAGS_SHOULD_RETRY|
* flags on |bio|. */
OPENSSL_EXPORT void BIO_set_retry_read(BIO *bio);
/* BIO_set_retry_read sets the |BIO_FLAGS_WRITE| and |BIO_FLAGS_SHOULD_RETRY|
* flags on |bio|. */
OPENSSL_EXPORT void BIO_set_retry_write(BIO *bio);
/* BIO_get_retry_flags gets the |BIO_FLAGS_READ|, |BIO_FLAGS_WRITE|,
* |BIO_FLAGS_IO_SPECIAL| and |BIO_FLAGS_SHOULD_RETRY| flags from |bio|. */
OPENSSL_EXPORT int BIO_get_retry_flags(BIO *bio);
/* BIO_clear_retry_flags clears the |BIO_FLAGS_READ|, |BIO_FLAGS_WRITE|,
* |BIO_FLAGS_IO_SPECIAL| and |BIO_FLAGS_SHOULD_RETRY| flags from |bio|. */
OPENSSL_EXPORT void BIO_clear_retry_flags(BIO *bio);
/* BIO_method_type returns the type of |bio|, which is one of the |BIO_TYPE_*|
* values. */
OPENSSL_EXPORT int BIO_method_type(const BIO *bio);
/* bio_info_cb is the type of a callback function that can be called for most
* BIO operations. The |event| argument is one of |BIO_CB_*| and can be ORed
* with |BIO_CB_RETURN| if the callback is being made after the operation in
* question. In that case, |return_value| will contain the return value from
* the operation. */
typedef long (*bio_info_cb)(BIO *bio, int event, const char *parg, int cmd,
long larg, long return_value);
/* BIO_callback_ctrl allows the callback function to be manipulated. The |cmd|
* arg will generally be |BIO_CTRL_SET_CALLBACK| but arbitary command values
* can be interpreted by the |BIO|. */
OPENSSL_EXPORT long BIO_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp);
/* BIO_pending returns the number of bytes pending to be read. */
OPENSSL_EXPORT size_t BIO_pending(const BIO *bio);
/* BIO_ctrl_pending calls |BIO_pending| and exists only for compatibility with
* OpenSSL. */
OPENSSL_EXPORT size_t BIO_ctrl_pending(const BIO *bio);
/* BIO_wpending returns the number of bytes pending to be written. */
OPENSSL_EXPORT size_t BIO_wpending(const BIO *bio);
/* BIO_set_close sets the close flag for |bio|. The meaning of which depends on
* the type of |bio| but, for example, a memory BIO interprets the close flag
* as meaning that it owns its buffer. It returns one on success and zero
* otherwise. */
OPENSSL_EXPORT int BIO_set_close(BIO *bio, int close_flag);
/* BIO_set_callback sets a callback function that will be called before and
* after most operations. See the comment above |bio_info_cb|. */
OPENSSL_EXPORT void BIO_set_callback(BIO *bio, bio_info_cb callback_func);
/* BIO_set_callback_arg sets the opaque pointer value that can be read within a
* callback with |BIO_get_callback_arg|. */
OPENSSL_EXPORT void BIO_set_callback_arg(BIO *bio, char *arg);
/* BIO_get_callback_arg returns the last value of the opaque callback pointer
* set by |BIO_set_callback_arg|. */
OPENSSL_EXPORT char *BIO_get_callback_arg(const BIO *bio);
/* BIO_number_read returns the number of bytes that have been read from
* |bio|. */
OPENSSL_EXPORT size_t BIO_number_read(const BIO *bio);
/* BIO_number_written returns the number of bytes that have been written to
* |bio|. */
OPENSSL_EXPORT size_t BIO_number_written(const BIO *bio);
/* Managing chains of BIOs.
*
* BIOs can be put into chains where the output of one is used as the input of
* the next etc. The most common case is a buffering BIO, which accepts and
* buffers writes until flushed into the next BIO in the chain. */
/* BIO_push adds |appended_bio| to the end of the chain with |bio| at the head.
* It returns |bio|. Note that |appended_bio| may be the head of a chain itself
* and thus this function can be used to join two chains.
*
* BIO_push takes ownership of the caller's reference to |appended_bio|. */
OPENSSL_EXPORT BIO *BIO_push(BIO *bio, BIO *appended_bio);
/* BIO_pop removes |bio| from the head of a chain and returns the next BIO in
* the chain, or NULL if there is no next BIO.
*
* The caller takes ownership of the chain's reference to |bio|. */
OPENSSL_EXPORT BIO *BIO_pop(BIO *bio);
/* BIO_next returns the next BIO in the chain after |bio|, or NULL if there is
* no such BIO. */
OPENSSL_EXPORT BIO *BIO_next(BIO *bio);
/* BIO_free_all calls |BIO_free|.
*
* TODO(fork): update callers and remove. */
OPENSSL_EXPORT void BIO_free_all(BIO *bio);
/* BIO_find_type walks a chain of BIOs and returns the first that matches
* |type|, which is one of the |BIO_TYPE_*| values. */
OPENSSL_EXPORT BIO *BIO_find_type(BIO *bio, int type);
/* BIO_copy_next_retry sets the retry flags and |retry_reason| of |bio| from
* the next BIO in the chain. */
OPENSSL_EXPORT void BIO_copy_next_retry(BIO *bio);
/* Printf functions.
*
* These functions are versions of printf functions that output to a BIO rather
* than a FILE. */
#ifdef __GNUC__
#define __bio_h__attr__ __attribute__
#else
#define __bio_h__attr__(x)
#endif
OPENSSL_EXPORT int BIO_printf(BIO *bio, const char *format, ...)
__bio_h__attr__((__format__(__printf__, 2, 3)));
#undef __bio_h__attr__
/* Utility functions. */
/* BIO_indent prints min(|indent|, |max_indent|) spaces. It returns one on
* success and zero otherwise. */
OPENSSL_EXPORT int BIO_indent(BIO *bio, unsigned indent, unsigned max_indent);
/* BIO_hexdump writes a hex dump of |data| to |bio|. Each line will be indented
* by |indent| spaces. */
OPENSSL_EXPORT int BIO_hexdump(BIO *bio, const uint8_t *data, size_t len,
unsigned indent);
/* BIO_print_errors prints the current contents of the error stack to |bio|
* using human readable strings where possible. */
OPENSSL_EXPORT void BIO_print_errors(BIO *bio);
/* BIO_read_asn1 reads a single ASN.1 object from |bio|. If successful it sets
* |*out| to be an allocated buffer (that should be freed with |OPENSSL_free|),
* |*out_size| to the length, in bytes, of that buffer and returns one.
* Otherwise it returns zero.
*
* If the length of the object is greater than |max_len| or 2^32 then the
* function will fail. Long-form tags are not supported. If the length of the
* object is indefinite the full contents of |bio| are read, unless it would be
* greater than |max_len|, in which case the function fails.
*
* If the function fails then some unknown amount of data may have been read
* from |bio|. */
OPENSSL_EXPORT int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len,
size_t max_len);
/* Memory BIOs.
*
* Memory BIOs can be used as a read-only source (with |BIO_new_mem_buf|) or a
* writable sink (with |BIO_new|, |BIO_s_mem| and |BIO_get_mem_buf|). Data
* written to a writable, memory BIO can be recalled by reading from it.
*
* Calling |BIO_reset| on a read-only BIO resets it to the original contents.
* On a writable BIO, it clears any data.
*
* If the close flag is set to |BIO_NOCLOSE| (not the default) then the
* underlying |BUF_MEM| will not be freed when the |BIO| is freed.
*
* Memory BIOs support |BIO_gets| and |BIO_puts|.
*
* |BIO_eof| is true if no data is in the BIO.
*
* |BIO_ctrl_pending| returns the number of bytes currently stored. */
/* BIO_s_mem returns a |BIO_METHOD| that uses a in-memory buffer. */
OPENSSL_EXPORT const BIO_METHOD *BIO_s_mem(void);
/* BIO_new_mem_buf creates BIO that reads and writes from |len| bytes at |buf|.
* It does not take ownership of |buf|. It returns the BIO or NULL on error.
*
* If |len| is negative, then |buf| is treated as a NUL-terminated string, but
* don't depend on this in new code. */
OPENSSL_EXPORT BIO *BIO_new_mem_buf(void *buf, int len);
/* BIO_mem_contents sets |*out_contents| to point to the current contents of
* |bio| and |*out_len| to contain the length of that data. It returns one on
* success and zero otherwise. */
OPENSSL_EXPORT int BIO_mem_contents(const BIO *bio,
const uint8_t **out_contents,
size_t *out_len);
/* BIO_get_mem_data sets |*contents| to point to the current contents of |bio|
* and returns the length of the data.
*
* WARNING: don't use this, use |BIO_mem_contents|. A return value of zero from
* this function can mean either that it failed or that the memory buffer is
* empty. */
OPENSSL_EXPORT long BIO_get_mem_data(BIO *bio, char **contents);
/* BIO_get_mem_ptr sets |*out| to a BUF_MEM containing the current contents of
* |bio|. It returns one on success or zero on error. */
OPENSSL_EXPORT int BIO_get_mem_ptr(BIO *bio, BUF_MEM **out);
/* BIO_set_mem_buf sets |b| as the contents of |bio|. If |take_ownership| is
* non-zero, then |b| will be freed when |bio| is closed. Returns one on
* success or zero otherwise. */
OPENSSL_EXPORT int BIO_set_mem_buf(BIO *bio, BUF_MEM *b, int take_ownership);
/* BIO_set_mem_eof_return sets the value that will be returned from reading
* |bio| when empty. If |eof_value| is zero then an empty memory BIO will
* return EOF (that is it will return zero and |BIO_should_retry| will be
* false). If |eof_value| is non zero then it will return |eof_value| when it
* is empty and it will set the read retry flag (that is |BIO_read_retry| is
* true). To avoid ambiguity with a normal positive return value, |eof_value|
* should be set to a negative value, typically -1.
*
* For a read-only BIO, the default is zero (EOF). For a writable BIO, the
* default is -1 so that additional data can be written once exhausted. */
OPENSSL_EXPORT int BIO_set_mem_eof_return(BIO *bio, int eof_value);
/* File descriptor BIOs.
*
* File descriptor BIOs are wrappers around the system's |read| and |write|
* functions. If the close flag is set then then |close| is called on the
* underlying file descriptor when the BIO is freed.
*
* |BIO_reset| attempts to seek the file pointer to the start of file using
* |lseek|.
*
* |BIO_seek| sets the file pointer to position |off| from start of file using
* |lseek|.
*
* |BIO_tell| returns the current file position. */
/* BIO_s_fd returns a |BIO_METHOD| for file descriptor fds. */
OPENSSL_EXPORT const BIO_METHOD *BIO_s_fd(void);
/* BIO_new_fd creates a new file descriptor BIO wrapping |fd|. If |close_flag|
* is non-zero, then |fd| will be closed when the BIO is. */
OPENSSL_EXPORT BIO *BIO_new_fd(int fd, int close_flag);
/* BIO_set_fd sets the file descriptor of |bio| to |fd|. If |close_flag| is
* non-zero then |fd| will be closed when |bio| is. It returns one on success
* or zero on error. */
OPENSSL_EXPORT int BIO_set_fd(BIO *bio, int fd, int close_flag);
/* BIO_get_fd sets |*out_fd| to the file descriptor currently in use by |bio|.
* It returns one on success and zero on error. */
OPENSSL_EXPORT int BIO_get_fd(BIO *bio, int *out_fd);
/* File BIOs.
*
* File BIOs are wrappers around a C |FILE| object.
*
* |BIO_flush| on a file BIO calls |fflush| on the wrapped stream.
*
* |BIO_reset| attempts to seek the file pointer to the start of file using
* |fseek|.
*
* |BIO_seek| sets the file pointer to the given position from the start of
* file using |fseek|.
*
* |BIO_eof| calls |feof|.
*
* Setting the close flag causes |fclose| to be called on the stream when the
* BIO is freed. */
/* BIO_s_file returns a BIO_METHOD that wraps a |FILE|. */
OPENSSL_EXPORT const BIO_METHOD *BIO_s_file(void);
/* BIO_new_file creates a file BIO by opening |filename| with the given mode.
* See the |fopen| manual page for details of the mode argument. */
OPENSSL_EXPORT BIO *BIO_new_file(const char *filename, const char *mode);
/* BIO_new_fp creates a new file BIO that wraps the given |FILE|. If
* |close_flag| is |BIO_CLOSE|, then |fclose| will be called on |stream| when
* the BIO is closed. */
OPENSSL_EXPORT BIO *BIO_new_fp(FILE *stream, int close_flag);
/* BIO_get_fp sets |*out_file| to the current |FILE| for |bio|. It returns one
* on success and zero otherwise. */
OPENSSL_EXPORT int BIO_get_fp(BIO *bio, FILE **out_file);
/* BIO_set_fp sets the |FILE| for |bio|. If |close_flag| is |BIO_CLOSE| then
* |fclose| will be called on |file| when |bio| is closed. It returns one on
* sucess and zero otherwise. */
OPENSSL_EXPORT int BIO_set_fp(BIO *bio, FILE *file, int close_flag);
/* BIO_read_filename opens |filename| for reading and sets the result as the
* |FILE| for |bio|. It returns one on success and zero otherwise. The |FILE|
* will be closed when |bio| is freed. */
OPENSSL_EXPORT int BIO_read_filename(BIO *bio, const char *filename);
/* BIO_write_filename opens |filename| for writing and sets the result as the
* |FILE| for |bio|. It returns one on success and zero otherwise. The |FILE|
* will be closed when |bio| is freed. */
OPENSSL_EXPORT int BIO_write_filename(BIO *bio, const char *filename);
/* BIO_append_filename opens |filename| for appending and sets the result as
* the |FILE| for |bio|. It returns one on success and zero otherwise. The
* |FILE| will be closed when |bio| is freed. */
OPENSSL_EXPORT int BIO_append_filename(BIO *bio, const char *filename);
/* BIO_rw_filename opens |filename| for reading and writing and sets the result
* as the |FILE| for |bio|. It returns one on success and zero otherwise. The
* |FILE| will be closed when |bio| is freed. */
OPENSSL_EXPORT int BIO_rw_filename(BIO *bio, const char *filename);
/* Buffer BIOs.
*
* Buffer BIOs are a filter-type BIO, i.e. they are designed to be used in a
* chain of BIOs. They provide buffering to reduce the number of operations on
* the underlying BIOs. */
OPENSSL_EXPORT const BIO_METHOD *BIO_f_buffer(void);
/* BIO_set_read_buffer_size sets the size, in bytes, of the read buffer and
* clears it. It returns one on success and zero on failure. */
OPENSSL_EXPORT int BIO_set_read_buffer_size(BIO *bio, int buffer_size);
/* BIO_set_write_buffer_size sets the size, in bytes, of the write buffer and
* clears it. It returns one on success and zero on failure. */
OPENSSL_EXPORT int BIO_set_write_buffer_size(BIO *bio, int buffer_size);
/* Socket BIOs. */
OPENSSL_EXPORT const BIO_METHOD *BIO_s_socket(void);
/* BIO_new_socket allocates and initialises a fresh BIO which will read and
* write to the socket |fd|. If |close_flag| is |BIO_CLOSE| then closing the
* BIO will close |fd|. It returns the fresh |BIO| or NULL on error. */
OPENSSL_EXPORT BIO *BIO_new_socket(int fd, int close_flag);
/* Connect BIOs.
*
* A connection BIO creates a network connection and transfers data over the
* resulting socket. */
OPENSSL_EXPORT const BIO_METHOD *BIO_s_connect(void);
/* BIO_new_connect returns a BIO that connects to the given hostname and port.
* The |host_and_optional_port| argument should be of the form
* "www.example.com" or "www.example.com:443". If the port is omitted, it must
* be provided with |BIO_set_conn_port|.
*
* It returns the new BIO on success, or NULL on error. */
OPENSSL_EXPORT BIO *BIO_new_connect(const char *host_and_optional_port);
/* BIO_set_conn_hostname sets |host_and_optional_port| as the hostname and
* optional port that |bio| will connect to. If the port is omitted, it must be
* provided with |BIO_set_conn_port|.
*
* It returns one on success and zero otherwise. */
OPENSSL_EXPORT int BIO_set_conn_hostname(BIO *bio,
const char *host_and_optional_port);
/* BIO_set_conn_port sets |port_str| as the port or service name that |bio|
* will connect to. It returns one on success and zero otherwise. */
OPENSSL_EXPORT int BIO_set_conn_port(BIO *bio, const char *port_str);
/* BIO_set_nbio sets whether |bio| will use non-blocking I/O operations. It
* returns one on success and zero otherwise. */
OPENSSL_EXPORT int BIO_set_nbio(BIO *bio, int on);
/* Datagram BIOs.
*
* TODO(fork): not implemented. */
#define BIO_CTRL_DGRAM_QUERY_MTU 40 /* as kernel for current MTU */
#define BIO_CTRL_DGRAM_SET_MTU 42 /* set cached value for MTU. want to use
this if asking the kernel fails */
#define BIO_CTRL_DGRAM_MTU_EXCEEDED 43 /* check whether the MTU was exceed in
the previous write operation. */
#define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT \
45 /* Next DTLS handshake timeout to adjust socket timeouts */
#define BIO_CTRL_DGRAM_GET_PEER 46
#define BIO_CTRL_DGRAM_GET_FALLBACK_MTU 47
/* BIO Pairs.
*
* BIO pairs provide a "loopback" like system: a pair of BIOs where data
* written to one can be read from the other and vice versa. */
/* BIO_new_bio_pair sets |*out1| and |*out2| to two freshly created BIOs where
* data written to one can be read from the other and vice versa. The
* |writebuf1| argument gives the size of the buffer used in |*out1| and
* |writebuf2| for |*out2|. It returns one on success and zero on error. */
OPENSSL_EXPORT int BIO_new_bio_pair(BIO **out1, size_t writebuf1, BIO **out2,
size_t writebuf2);
/* BIO_new_bio_pair_external_buf is the same as |BIO_new_bio_pair| with the
* difference that the caller keeps ownership of the write buffers
* |ext_writebuf1_len| and |ext_writebuf2_len|. This is useful when using zero
* copy API for read and write operations, in cases where the buffers need to
* outlive the BIO pairs. It returns one on success and zero on error. */
OPENSSL_EXPORT int BIO_new_bio_pair_external_buf(BIO** bio1_p,
size_t writebuf1_len,
uint8_t* ext_writebuf1,
BIO** bio2_p,
size_t writebuf2_len,
uint8_t* ext_writebuf2);
/* BIO_ctrl_get_read_request returns the number of bytes that the other side of
* |bio| tried (unsuccessfully) to read. */
OPENSSL_EXPORT size_t BIO_ctrl_get_read_request(BIO *bio);
/* BIO_ctrl_get_write_guarantee returns the number of bytes that |bio| (which
* must have been returned by |BIO_new_bio_pair|) will accept on the next
* |BIO_write| call. */
OPENSSL_EXPORT size_t BIO_ctrl_get_write_guarantee(BIO *bio);
/* BIO_shutdown_wr marks |bio| as closed, from the point of view of the other
* side of the pair. Future |BIO_write| calls on |bio| will fail. It returns
* one on success and zero otherwise. */
OPENSSL_EXPORT int BIO_shutdown_wr(BIO *bio);
/* Zero copy versions of BIO_read and BIO_write for BIO pairs. */
/* BIO_zero_copy_get_read_buf initiates a zero copy read operation.
* |out_read_buf| is set to the internal read buffer, and |out_buf_offset| is
* set to the current read position of |out_read_buf|. The number of bytes
* available for read from |out_read_buf| + |out_buf_offset| is returned in
* |out_available_bytes|. Note that this function might report fewer bytes
* available than |BIO_pending|, if the internal ring buffer is wrapped. It
* returns one on success. In case of error it returns zero and pushes to the
* error stack.
*
* The zero copy read operation is completed by calling
* |BIO_zero_copy_get_read_buf_done|. Neither |BIO_zero_copy_get_read_buf| nor
* any other I/O read operation may be called while a zero copy read operation
* is active. */
OPENSSL_EXPORT int BIO_zero_copy_get_read_buf(BIO* bio,
uint8_t** out_read_buf,
size_t* out_buf_offset,
size_t* out_available_bytes);
/* BIO_zero_copy_get_read_buf_done must be called after reading from a BIO using
* |BIO_zero_copy_get_read_buf| to finish the read operation. The |bytes_read|
* argument is the number of bytes read.
*
* It returns one on success. In case of error it returns zero and pushes to the
* error stack. */
OPENSSL_EXPORT int BIO_zero_copy_get_read_buf_done(BIO* bio, size_t bytes_read);
/* BIO_zero_copy_get_write_buf_done initiates a zero copy write operation.
* |out_write_buf| is set to to the internal write buffer, and |out_buf_offset|
* is set to the current write position of |out_write_buf|.
* The number of bytes available for write from |out_write_buf| +
* |out_buf_offset| is returned in |out_available_bytes|. Note that this
* function might report fewer bytes available than
* |BIO_ctrl_get_write_guarantee|, if the internal buffer is wrapped. It returns
* one on success. In case of error it returns zero and pushes to the error
* stack.
*
* The zero copy write operation is completed by calling
* |BIO_zero_copy_write_buf_done|. Neither |BIO_zero_copy_get_write_buf|
* nor any other I/O write operation may be called while a zero copy write
* operation is active. */
OPENSSL_EXPORT int BIO_zero_copy_get_write_buf(BIO* bio,
uint8_t** out_write_buf,
size_t* out_buf_offset,
size_t* out_available_bytes);
/* BIO_zero_copy_write_buf_done must be called after writing to a BIO using
* |BIO_zero_copy_get_write_buf_done| to finish the write operation. The
* |bytes_written| argument gives the number of bytes written.
*
* It returns one on success. In case of error it returns zero and pushes to the
* error stack. */
OPENSSL_EXPORT int BIO_zero_copy_get_write_buf_done(BIO* bio,
size_t bytes_written);
/* BIO_NOCLOSE and |BIO_CLOSE| can be used as symbolic arguments when a "close
* flag" is passed to a BIO function. */
#define BIO_NOCLOSE 0
#define BIO_CLOSE 1
/* These are passed to the BIO callback */
#define BIO_CB_FREE 0x01
#define BIO_CB_READ 0x02
#define BIO_CB_WRITE 0x03
#define BIO_CB_PUTS 0x04
#define BIO_CB_GETS 0x05
#define BIO_CB_CTRL 0x06
/* The callback is called before and after the underling operation,
* The BIO_CB_RETURN flag indicates if it is after the call */
#define BIO_CB_RETURN 0x80
/* These are values of the |cmd| argument to |BIO_ctrl|. */
#define BIO_CTRL_RESET 1 /* opt - rewind/zero etc */
#define BIO_CTRL_EOF 2 /* opt - are we at the eof */
#define BIO_CTRL_INFO 3 /* opt - extra tit-bits */
#define BIO_CTRL_SET 4 /* man - set the 'IO' type */
#define BIO_CTRL_GET 5 /* man - get the 'IO' type */
#define BIO_CTRL_GET_CLOSE 8 /* man - set the 'close' on free */
#define BIO_CTRL_SET_CLOSE 9 /* man - set the 'close' on free */
#define BIO_CTRL_PENDING 10 /* opt - is their more data buffered */
#define BIO_CTRL_FLUSH 11 /* opt - 'flush' buffered output */
#define BIO_CTRL_WPENDING 13 /* opt - number of bytes still to write */
/* callback is int cb(BIO *bio,state,ret); */
#define BIO_CTRL_SET_CALLBACK 14 /* opt - set callback function */
#define BIO_CTRL_GET_CALLBACK 15 /* opt - set callback function */
#define BIO_CTRL_SET_FILENAME 30 /* BIO_s_file special */
/* Android compatibility section.
*
* A previous version of BoringSSL used in Android renamed ERR_print_errors_fp
* to BIO_print_errors_fp. It has subsequently been renamed back to
* ERR_print_errors_fp. */
#define BIO_print_errors_fp ERR_print_errors_fp
/* Private functions */
#define BIO_FLAGS_READ 0x01
#define BIO_FLAGS_WRITE 0x02
#define BIO_FLAGS_IO_SPECIAL 0x04
#define BIO_FLAGS_RWS (BIO_FLAGS_READ | BIO_FLAGS_WRITE | BIO_FLAGS_IO_SPECIAL)
#define BIO_FLAGS_SHOULD_RETRY 0x08
#define BIO_FLAGS_BASE64_NO_NL 0x100
/* This is used with memory BIOs: it means we shouldn't free up or change the
* data in any way. */
#define BIO_FLAGS_MEM_RDONLY 0x200
/* These are the 'types' of BIOs */
#define BIO_TYPE_NONE 0
#define BIO_TYPE_MEM (1 | 0x0400)
#define BIO_TYPE_FILE (2 | 0x0400)
#define BIO_TYPE_FD (4 | 0x0400 | 0x0100)
#define BIO_TYPE_SOCKET (5 | 0x0400 | 0x0100)
#define BIO_TYPE_NULL (6 | 0x0400)
#define BIO_TYPE_SSL (7 | 0x0200)
#define BIO_TYPE_MD (8 | 0x0200) /* passive filter */
#define BIO_TYPE_BUFFER (9 | 0x0200) /* filter */
#define BIO_TYPE_CIPHER (10 | 0x0200) /* filter */
#define BIO_TYPE_BASE64 (11 | 0x0200) /* filter */
#define BIO_TYPE_CONNECT (12 | 0x0400 | 0x0100) /* socket - connect */
#define BIO_TYPE_ACCEPT (13 | 0x0400 | 0x0100) /* socket for accept */
#define BIO_TYPE_PROXY_CLIENT (14 | 0x0200) /* client proxy BIO */
#define BIO_TYPE_PROXY_SERVER (15 | 0x0200) /* server proxy BIO */
#define BIO_TYPE_NBIO_TEST (16 | 0x0200) /* server proxy BIO */
#define BIO_TYPE_NULL_FILTER (17 | 0x0200)
#define BIO_TYPE_BER (18 | 0x0200) /* BER -> bin filter */
#define BIO_TYPE_BIO (19 | 0x0400) /* (half a) BIO pair */
#define BIO_TYPE_LINEBUFFER (20 | 0x0200) /* filter */
#define BIO_TYPE_DGRAM (21 | 0x0400 | 0x0100)
#define BIO_TYPE_ASN1 (22 | 0x0200) /* filter */
#define BIO_TYPE_COMP (23 | 0x0200) /* filter */
#define BIO_TYPE_DESCRIPTOR 0x0100 /* socket, fd, connect or accept */
#define BIO_TYPE_FILTER 0x0200
#define BIO_TYPE_SOURCE_SINK 0x0400
struct bio_method_st {
int type;
const char *name;
int (*bwrite)(BIO *, const char *, int);
int (*bread)(BIO *, char *, int);
/* TODO(fork): remove bputs. */
int (*bputs)(BIO *, const char *);
int (*bgets)(BIO *, char *, int);
long (*ctrl)(BIO *, int, long, void *);
int (*create)(BIO *);
int (*destroy)(BIO *);
long (*callback_ctrl)(BIO *, int, bio_info_cb);
};
struct bio_st {
const BIO_METHOD *method;
/* bio, mode, argp, argi, argl, ret */
long (*callback)(struct bio_st *, int, const char *, int, long, long);
char *cb_arg; /* first argument for the callback */
/* init is non-zero if this |BIO| has been initialised. */
int init;
/* shutdown is often used by specific |BIO_METHOD|s to determine whether
* they own some underlying resource. This flag can often by controlled by
* |BIO_set_close|. For example, whether an fd BIO closes the underlying fd
* when it, itself, is closed. */
int shutdown;
int flags;
int retry_reason;
/* num is a BIO-specific value. For example, in fd BIOs it's used to store a
* file descriptor. */
int num;
CRYPTO_refcount_t references;
void *ptr;
/* next_bio points to the next |BIO| in a chain. This |BIO| owns a reference
* to |next_bio|. */
struct bio_st *next_bio; /* used by filter BIOs */
size_t num_read, num_write;
};
#define BIO_C_SET_CONNECT 100
#define BIO_C_DO_STATE_MACHINE 101
#define BIO_C_SET_NBIO 102
#define BIO_C_SET_PROXY_PARAM 103
#define BIO_C_SET_FD 104
#define BIO_C_GET_FD 105
#define BIO_C_SET_FILE_PTR 106
#define BIO_C_GET_FILE_PTR 107
#define BIO_C_SET_FILENAME 108
#define BIO_C_SET_SSL 109
#define BIO_C_GET_SSL 110
#define BIO_C_SET_MD 111
#define BIO_C_GET_MD 112
#define BIO_C_GET_CIPHER_STATUS 113
#define BIO_C_SET_BUF_MEM 114
#define BIO_C_GET_BUF_MEM_PTR 115
#define BIO_C_GET_BUFF_NUM_LINES 116
#define BIO_C_SET_BUFF_SIZE 117
#define BIO_C_SET_ACCEPT 118
#define BIO_C_SSL_MODE 119
#define BIO_C_GET_MD_CTX 120
#define BIO_C_GET_PROXY_PARAM 121
#define BIO_C_SET_BUFF_READ_DATA 122 /* data to read first */
#define BIO_C_GET_CONNECT 123
#define BIO_C_GET_ACCEPT 124
#define BIO_C_SET_SSL_RENEGOTIATE_BYTES 125
#define BIO_C_GET_SSL_NUM_RENEGOTIATES 126
#define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT 127
#define BIO_C_FILE_SEEK 128
#define BIO_C_GET_CIPHER_CTX 129
#define BIO_C_SET_BUF_MEM_EOF_RETURN 130/*return end of input value*/
#define BIO_C_SET_BIND_MODE 131
#define BIO_C_GET_BIND_MODE 132
#define BIO_C_FILE_TELL 133
#define BIO_C_GET_SOCKS 134
#define BIO_C_SET_SOCKS 135
#define BIO_C_SET_WRITE_BUF_SIZE 136/* for BIO_s_bio */
#define BIO_C_GET_WRITE_BUF_SIZE 137
#define BIO_C_GET_WRITE_GUARANTEE 140
#define BIO_C_GET_READ_REQUEST 141
#define BIO_C_SHUTDOWN_WR 142
#define BIO_C_NREAD0 143
#define BIO_C_NREAD 144
#define BIO_C_NWRITE0 145
#define BIO_C_NWRITE 146
#define BIO_C_RESET_READ_REQUEST 147
#define BIO_C_SET_MD_CTX 148
#define BIO_C_SET_PREFIX 149
#define BIO_C_GET_PREFIX 150
#define BIO_C_SET_SUFFIX 151
#define BIO_C_GET_SUFFIX 152
#define BIO_C_SET_EX_ARG 153
#define BIO_C_GET_EX_ARG 154
#if defined(__cplusplus)
} /* extern C */
#endif
#define BIO_F_BIO_callback_ctrl 100
#define BIO_F_BIO_ctrl 101
#define BIO_F_BIO_new 102
#define BIO_F_BIO_new_file 103
#define BIO_F_BIO_new_mem_buf 104
#define BIO_F_BIO_zero_copy_get_read_buf 105
#define BIO_F_BIO_zero_copy_get_read_buf_done 106
#define BIO_F_BIO_zero_copy_get_write_buf 107
#define BIO_F_BIO_zero_copy_get_write_buf_done 108
#define BIO_F_bio_io 109
#define BIO_F_bio_make_pair 110
#define BIO_F_bio_write 111
#define BIO_F_buffer_ctrl 112
#define BIO_F_conn_ctrl 113
#define BIO_F_conn_state 114
#define BIO_F_file_ctrl 115
#define BIO_F_file_read 116
#define BIO_F_mem_write 117
#define BIO_F_BIO_printf 118
#define BIO_R_BAD_FOPEN_MODE 100
#define BIO_R_BROKEN_PIPE 101
#define BIO_R_CONNECT_ERROR 102
#define BIO_R_ERROR_SETTING_NBIO 103
#define BIO_R_INVALID_ARGUMENT 104
#define BIO_R_IN_USE 105
#define BIO_R_KEEPALIVE 106
#define BIO_R_NBIO_CONNECT_ERROR 107
#define BIO_R_NO_HOSTNAME_SPECIFIED 108
#define BIO_R_NO_PORT_SPECIFIED 109
#define BIO_R_NO_SUCH_FILE 110
#define BIO_R_NULL_PARAMETER 111
#define BIO_R_SYS_LIB 112
#define BIO_R_UNABLE_TO_CREATE_SOCKET 113
#define BIO_R_UNINITIALIZED 114
#define BIO_R_UNSUPPORTED_METHOD 115
#define BIO_R_WRITE_TO_READ_ONLY_BIO 116
#endif /* OPENSSL_HEADER_BIO_H */

@ -1,93 +0,0 @@
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
#ifndef OPENSSL_HEADER_BLOWFISH_H
#define OPENSSL_HEADER_BLOWFISH_H
#include <openssl/base.h>
#ifdef __cplusplus
extern "C" {
#endif
#define BF_ENCRYPT 1
#define BF_DECRYPT 0
#define BF_ROUNDS 16
#define BF_BLOCK 8
typedef struct bf_key_st {
uint32_t P[BF_ROUNDS + 2];
uint32_t S[4 * 256];
} BF_KEY;
OPENSSL_EXPORT void BF_set_key(BF_KEY *key, size_t len, const uint8_t *data);
OPENSSL_EXPORT void BF_encrypt(uint32_t *data, const BF_KEY *key);
OPENSSL_EXPORT void BF_decrypt(uint32_t *data, const BF_KEY *key);
OPENSSL_EXPORT void BF_ecb_encrypt(const uint8_t *in, uint8_t *out,
const BF_KEY *key, int enc);
OPENSSL_EXPORT void BF_cbc_encrypt(const uint8_t *in, uint8_t *out, long length,
const BF_KEY *schedule, uint8_t *ivec,
int enc);
#ifdef __cplusplus
}
#endif
#endif /* OPENSSL_HEADER_BLOWFISH_H */

@ -1,875 +0,0 @@
/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
/* ====================================================================
* Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* openssl-core@openssl.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com).
*
*/
/* ====================================================================
* Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
*
* Portions of the attached software ("Contribution") are developed by
* SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
*
* The Contribution is licensed pursuant to the Eric Young open source
* license provided above.
*
* The binary polynomial arithmetic software is originally written by
* Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
* Laboratories. */
#ifndef OPENSSL_HEADER_BN_H
#define OPENSSL_HEADER_BN_H
#include <openssl/base.h>
#include <openssl/thread.h>
#include <inttypes.h> /* for PRIu64 and friends */
#include <stdio.h> /* for FILE* */
#if defined(__cplusplus)
extern "C" {
#endif
/* BN provides support for working with arbitary sized integers. For example,
* although the largest integer supported by the compiler might be 64 bits, BN
* will allow you to work with numbers until you run out of memory. */
/* BN_ULONG is the native word size when working with big integers.
*
* Note: on some platforms, inttypes.h does not define print format macros in
* C++ unless |__STDC_FORMAT_MACROS| defined. As this is a public header, bn.h
* does not define |__STDC_FORMAT_MACROS| itself. C++ source files which use the
* FMT macros must define it externally. */
#if defined(OPENSSL_64_BIT)
#define BN_ULONG uint64_t
#define BN_BITS2 64
#define BN_DEC_FMT1 "%" PRIu64
#define BN_DEC_FMT2 "%019" PRIu64
#define BN_HEX_FMT1 "%" PRIx64
#elif defined(OPENSSL_32_BIT)
#define BN_ULONG uint32_t
#define BN_BITS2 32
#define BN_DEC_FMT1 "%" PRIu32
#define BN_DEC_FMT2 "%09" PRIu32
#define BN_HEX_FMT1 "%" PRIx32
#else
#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT"
#endif
/* Allocation and freeing. */
/* BN_new creates a new, allocated BIGNUM and initialises it. */
OPENSSL_EXPORT BIGNUM *BN_new(void);
/* BN_init initialises a stack allocated |BIGNUM|. */
OPENSSL_EXPORT void BN_init(BIGNUM *bn);
/* BN_free frees the data referenced by |bn| and, if |bn| was originally
* allocated on the heap, frees |bn| also. */
OPENSSL_EXPORT void BN_free(BIGNUM *bn);
/* BN_clear_free erases and frees the data referenced by |bn| and, if |bn| was
* originally allocated on the heap, frees |bn| also. */
OPENSSL_EXPORT void BN_clear_free(BIGNUM *bn);
/* BN_dup allocates a new BIGNUM and sets it equal to |src|. It returns the
* allocated BIGNUM on success or NULL otherwise. */
OPENSSL_EXPORT BIGNUM *BN_dup(const BIGNUM *src);
/* BN_copy sets |dest| equal to |src| and returns |dest|. */
OPENSSL_EXPORT BIGNUM *BN_copy(BIGNUM *dest, const BIGNUM *src);
/* BN_clear sets |bn| to zero and erases the old data. */
OPENSSL_EXPORT void BN_clear(BIGNUM *bn);
/* BN_value_one returns a static BIGNUM with value 1. */
OPENSSL_EXPORT const BIGNUM *BN_value_one(void);
/* BN_with_flags initialises a stack allocated |BIGNUM| with pointers to the
* contents of |in| but with |flags| ORed into the flags field.
*
* Note: the two BIGNUMs share state and so |out| should /not/ be passed to
* |BN_free|. */
OPENSSL_EXPORT void BN_with_flags(BIGNUM *out, const BIGNUM *in, int flags);
/* Basic functions. */
/* BN_num_bits returns the minimum number of bits needed to represent the
* absolute value of |bn|. */
OPENSSL_EXPORT unsigned BN_num_bits(const BIGNUM *bn);
/* BN_num_bytes returns the minimum number of bytes needed to represent the
* absolute value of |bn|. */
OPENSSL_EXPORT unsigned BN_num_bytes(const BIGNUM *bn);
/* BN_zero sets |bn| to zero. */
OPENSSL_EXPORT void BN_zero(BIGNUM *bn);
/* BN_one sets |bn| to one. It returns one on success or zero on allocation
* failure. */
OPENSSL_EXPORT int BN_one(BIGNUM *bn);
/* BN_set_word sets |bn| to |value|. It returns one on success or zero on
* allocation failure. */
OPENSSL_EXPORT int BN_set_word(BIGNUM *bn, BN_ULONG value);
/* BN_set_negative sets the sign of |bn|. */
OPENSSL_EXPORT void BN_set_negative(BIGNUM *bn, int sign);
/* BN_is_negative returns one if |bn| is negative and zero otherwise. */
OPENSSL_EXPORT int BN_is_negative(const BIGNUM *bn);
/* BN_get_flags returns |bn->flags| & |flags|. */
OPENSSL_EXPORT int BN_get_flags(const BIGNUM *bn, int flags);
/* BN_set_flags sets |flags| on |bn|. */
OPENSSL_EXPORT void BN_set_flags(BIGNUM *bn, int flags);
/* Conversion functions. */
/* BN_bin2bn sets |*ret| to the value of |len| bytes from |in|, interpreted as
* a big-endian number, and returns |ret|. If |ret| is NULL then a fresh
* |BIGNUM| is allocated and returned. It returns NULL on allocation
* failure. */
OPENSSL_EXPORT BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret);
/* BN_bn2bin serialises the absolute value of |in| to |out| as a big-endian
* integer, which must have |BN_num_bytes| of space available. It returns the
* number of bytes written. */
OPENSSL_EXPORT size_t BN_bn2bin(const BIGNUM *in, uint8_t *out);
/* BN_bn2bin_padded serialises the absolute value of |in| to |out| as a
* big-endian integer. The integer is padded with leading zeros up to size
* |len|. If |len| is smaller than |BN_num_bytes|, the function fails and
* returns 0. Otherwise, it returns 1. */
OPENSSL_EXPORT int BN_bn2bin_padded(uint8_t *out, size_t len, const BIGNUM *in);
/* BN_bn2hex returns an allocated string that contains a NUL-terminated, hex
* representation of |bn|. If |bn| is negative, the first char in the resulting
* string will be '-'. Returns NULL on allocation failure. */
OPENSSL_EXPORT char *BN_bn2hex(const BIGNUM *bn);
/* BN_hex2bn parses the leading hex number from |in|, which may be proceeded by
* a '-' to indicate a negative number and may contain trailing, non-hex data.
* If |outp| is not NULL, it constructs a BIGNUM equal to the hex number and
* stores it in |*outp|. If |*outp| is NULL then it allocates a new BIGNUM and
* updates |*outp|. It returns the number of bytes of |in| processed or zero on
* error. */
OPENSSL_EXPORT int BN_hex2bn(BIGNUM **outp, const char *in);
/* BN_bn2dec returns an allocated string that contains a NUL-terminated,
* decimal representation of |bn|. If |bn| is negative, the first char in the
* resulting string will be '-'. Returns NULL on allocation failure. */
OPENSSL_EXPORT char *BN_bn2dec(const BIGNUM *a);
/* BN_dec2bn parses the leading decimal number from |in|, which may be
* proceeded by a '-' to indicate a negative number and may contain trailing,
* non-decimal data. If |outp| is not NULL, it constructs a BIGNUM equal to the
* decimal number and stores it in |*outp|. If |*outp| is NULL then it
* allocates a new BIGNUM and updates |*outp|. It returns the number of bytes
* of |in| processed or zero on error. */
OPENSSL_EXPORT int BN_dec2bn(BIGNUM **outp, const char *in);
/* BN_asc2bn acts like |BN_dec2bn| or |BN_hex2bn| depending on whether |in|
* begins with "0X" or "0x" (indicating hex) or not (indicating decimal). A
* leading '-' is still permitted and comes before the optional 0X/0x. It
* returns one on success or zero on error. */
OPENSSL_EXPORT int BN_asc2bn(BIGNUM **outp, const char *in);
/* BN_print writes a hex encoding of |a| to |bio|. It returns one on success
* and zero on error. */
OPENSSL_EXPORT int BN_print(BIO *bio, const BIGNUM *a);
/* BN_print_fp acts like |BIO_print|, but wraps |fp| in a |BIO| first. */
OPENSSL_EXPORT int BN_print_fp(FILE *fp, const BIGNUM *a);
/* BN_get_word returns the absolute value of |bn| as a single word. If |bn| is
* too large to be represented as a single word, the maximum possible value
* will be returned. */
OPENSSL_EXPORT BN_ULONG BN_get_word(const BIGNUM *bn);
/* Internal functions.
*
* These functions are useful for code that is doing low-level manipulations of
* BIGNUM values. However, be sure that no other function in this file does
* what you want before turning to these. */
/* bn_correct_top decrements |bn->top| until |bn->d[top-1]| is non-zero or
* until |top| is zero. */
OPENSSL_EXPORT void bn_correct_top(BIGNUM *bn);
/* bn_wexpand ensures that |bn| has at least |words| works of space without
* altering its value. It returns one on success or zero on allocation
* failure. */
OPENSSL_EXPORT BIGNUM *bn_wexpand(BIGNUM *bn, unsigned words);
/* BIGNUM pools.
*
* Certain BIGNUM operations need to use many temporary variables and
* allocating and freeing them can be quite slow. Thus such opertions typically
* take a |BN_CTX| parameter, which contains a pool of |BIGNUMs|. The |ctx|
* argument to a public function may be NULL, in which case a local |BN_CTX|
* will be created just for the lifetime of that call.
*
* A function must call |BN_CTX_start| first. Then, |BN_CTX_get| may be called
* repeatedly to obtain temporary |BIGNUM|s. All |BN_CTX_get| calls must be made
* before calling any other functions that use the |ctx| as an argument.
*
* Finally, |BN_CTX_end| must be called before returning from the function.
* When |BN_CTX_end| is called, the |BIGNUM| pointers obtained from
* |BN_CTX_get| become invalid. */
/* BN_CTX_new returns a new, empty BN_CTX or NULL on allocation failure. */
OPENSSL_EXPORT BN_CTX *BN_CTX_new(void);
/* BN_CTX_free frees all BIGNUMs contained in |ctx| and then frees |ctx|
* itself. */
OPENSSL_EXPORT void BN_CTX_free(BN_CTX *ctx);
/* BN_CTX_start "pushes" a new entry onto the |ctx| stack and allows future
* calls to |BN_CTX_get|. */
OPENSSL_EXPORT void BN_CTX_start(BN_CTX *ctx);
/* BN_CTX_get returns a new |BIGNUM|, or NULL on allocation failure. Once
* |BN_CTX_get| has returned NULL, all future calls will also return NULL until
* |BN_CTX_end| is called. */
OPENSSL_EXPORT BIGNUM *BN_CTX_get(BN_CTX *ctx);
/* BN_CTX_end invalidates all |BIGNUM|s returned from |BN_CTX_get| since the
* matching |BN_CTX_start| call. */
OPENSSL_EXPORT void BN_CTX_end(BN_CTX *ctx);
/* Simple arithmetic */
/* BN_add sets |r| = |a| + |b|, where |r| may be the same pointer as either |a|
* or |b|. It returns one on success and zero on allocation failure. */
OPENSSL_EXPORT int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
/* BN_uadd sets |r| = |a| + |b|, where |a| and |b| are non-negative and |r| may
* be the same pointer as either |a| or |b|. It returns one on success and zero
* on allocation failure. */
OPENSSL_EXPORT int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
/* BN_add_word adds |w| to |a|. It returns one on success and zero otherwise. */
OPENSSL_EXPORT int BN_add_word(BIGNUM *a, BN_ULONG w);
/* BN_sub sets |r| = |a| - |b|, where |r| must be a distinct pointer from |a|
* and |b|. It returns one on success and zero on allocation failure. */
OPENSSL_EXPORT int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
/* BN_usub sets |r| = |a| - |b|, where |a| and |b| are non-negative integers,
* |b| < |a| and |r| must be a distinct pointer from |a| and |b|. It returns
* one on success and zero on allocation failure. */
OPENSSL_EXPORT int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b);
/* BN_sub_word subtracts |w| from |a|. It returns one on success and zero on
* allocation failure. */
OPENSSL_EXPORT int BN_sub_word(BIGNUM *a, BN_ULONG w);
/* BN_mul sets |r| = |a| * |b|, where |r| may be the same pointer as |a| or
* |b|. Returns one on success and zero otherwise. */
OPENSSL_EXPORT int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
BN_CTX *ctx);
/* BN_mul_word sets |bn| = |bn| * |w|. It returns one on success or zero on
* allocation failure. */
OPENSSL_EXPORT int BN_mul_word(BIGNUM *bn, BN_ULONG w);
/* BN_sqr sets |r| = |a|^2 (i.e. squares), where |r| may be the same pointer as
* |a|. Returns one on success and zero otherwise. This is more efficient than
* BN_mul(r, a, a, ctx). */
OPENSSL_EXPORT int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx);
/* BN_div divides |numerator| by |divisor| and places the result in |quotient|
* and the remainder in |rem|. Either of |quotient| or |rem| may be NULL, in
* which case the respective value is not returned. The result is rounded
* towards zero; thus if |numerator| is negative, the remainder will be zero or
* negative. It returns one on success or zero on error. */
OPENSSL_EXPORT int BN_div(BIGNUM *quotient, BIGNUM *rem,
const BIGNUM *numerator, const BIGNUM *divisor,
BN_CTX *ctx);
/* BN_div_word sets |numerator| = |numerator|/|divisor| and returns the
* remainder or (BN_ULONG)-1 on error. */
OPENSSL_EXPORT BN_ULONG BN_div_word(BIGNUM *numerator, BN_ULONG divisor);
/* BN_sqrt sets |*out_sqrt| (which may be the same |BIGNUM| as |in|) to the
* square root of |in|, using |ctx|. It returns one on success or zero on
* error. Negative numbers and non-square numbers will result in an error with
* appropriate errors on the error queue. */
OPENSSL_EXPORT int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx);
/* Comparison functions */
/* BN_cmp returns a value less than, equal to or greater than zero if |a| is
* less than, equal to or greater than |b|, respectively. */
OPENSSL_EXPORT int BN_cmp(const BIGNUM *a, const BIGNUM *b);
/* BN_ucmp returns a value less than, equal to or greater than zero if the
* absolute value of |a| is less than, equal to or greater than the absolute
* value of |b|, respectively. */
OPENSSL_EXPORT int BN_ucmp(const BIGNUM *a, const BIGNUM *b);
/* BN_abs_is_word returns one if the absolute value of |bn| equals |w| and zero
* otherwise. */
OPENSSL_EXPORT int BN_abs_is_word(const BIGNUM *bn, BN_ULONG w);
/* BN_is_zero returns one if |bn| is zero and zero otherwise. */
OPENSSL_EXPORT int BN_is_zero(const BIGNUM *bn);
/* BN_is_one returns one if |bn| equals one and zero otherwise. */
OPENSSL_EXPORT int BN_is_one(const BIGNUM *bn);
/* BN_is_word returns one if |bn| is exactly |w| and zero otherwise. */
OPENSSL_EXPORT int BN_is_word(const BIGNUM *bn, BN_ULONG w);
/* BN_is_odd returns one if |bn| is odd and zero otherwise. */
OPENSSL_EXPORT int BN_is_odd(const BIGNUM *bn);
/* Bitwise operations. */
/* BN_lshift sets |r| equal to |a| << n. The |a| and |r| arguments may be the
* same |BIGNUM|. It returns one on success and zero on allocation failure. */
OPENSSL_EXPORT int BN_lshift(BIGNUM *r, const BIGNUM *a, int n);
/* BN_lshift1 sets |r| equal to |a| << 1, where |r| and |a| may be the same
* pointer. It returns one on success and zero on allocation failure. */
OPENSSL_EXPORT int BN_lshift1(BIGNUM *r, const BIGNUM *a);
/* BN_rshift sets |r| equal to |a| >> n, where |r| and |a| may be the same
* pointer. It returns one on success and zero on allocation failure. */
OPENSSL_EXPORT int BN_rshift(BIGNUM *r, const BIGNUM *a, int n);
/* BN_rshift1 sets |r| equal to |a| >> 1, where |r| and |a| may be the same
* pointer. It returns one on success and zero on allocation failure. */
OPENSSL_EXPORT int BN_rshift1(BIGNUM *r, const BIGNUM *a);
/* BN_set_bit sets the |n|th, least-significant bit in |a|. For example, if |a|
* is 2 then setting bit zero will make it 3. It returns one on success or zero
* on allocation failure. */
OPENSSL_EXPORT int BN_set_bit(BIGNUM *a, int n);
/* BN_clear_bit clears the |n|th, least-significant bit in |a|. For example, if
* |a| is 3, clearing bit zero will make it two. It returns one on success or
* zero on allocation failure. */
OPENSSL_EXPORT int BN_clear_bit(BIGNUM *a, int n);
/* BN_is_bit_set returns the value of the |n|th, least-significant bit in |a|,
* or zero if the bit doesn't exist. */
OPENSSL_EXPORT int BN_is_bit_set(const BIGNUM *a, int n);
/* BN_mask_bits truncates |a| so that it is only |n| bits long. It returns one
* on success or zero if |n| is greater than the length of |a| already. */
OPENSSL_EXPORT int BN_mask_bits(BIGNUM *a, int n);
/* Modulo arithmetic. */
/* BN_mod_word returns |a| mod |w|. */
OPENSSL_EXPORT BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w);
/* BN_mod is a helper macro that calls |BN_div| and discards the quotient. */
#define BN_mod(rem, numerator, divisor, ctx) \
BN_div(NULL, (rem), (numerator), (divisor), (ctx))
/* BN_nnmod is a non-negative modulo function. It acts like |BN_mod|, but 0 <=
* |rem| < |divisor| is always true. It returns one on success and zero on
* error. */
OPENSSL_EXPORT int BN_nnmod(BIGNUM *rem, const BIGNUM *numerator,
const BIGNUM *divisor, BN_CTX *ctx);
/* BN_mod_add sets |r| = |a| + |b| mod |m|. It returns one on success and zero
* on error. */
OPENSSL_EXPORT int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
const BIGNUM *m, BN_CTX *ctx);
/* BN_mod_add_quick acts like |BN_mod_add| but requires that |a| and |b| be
* non-negative and less than |m|. */
OPENSSL_EXPORT int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
const BIGNUM *m);
/* BN_mod_sub sets |r| = |a| - |b| mod |m|. It returns one on success and zero
* on error. */
OPENSSL_EXPORT int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
const BIGNUM *m, BN_CTX *ctx);
/* BN_mod_sub_quick acts like |BN_mod_sub| but requires that |a| and |b| be
* non-negative and less than |m|. */
OPENSSL_EXPORT int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
const BIGNUM *m);
/* BN_mod_mul sets |r| = |a|*|b| mod |m|. It returns one on success and zero
* on error. */
OPENSSL_EXPORT int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
const BIGNUM *m, BN_CTX *ctx);
/* BN_mod_mul sets |r| = |a|^2 mod |m|. It returns one on success and zero
* on error. */
OPENSSL_EXPORT int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m,
BN_CTX *ctx);
/* BN_mod_lshift sets |r| = (|a| << n) mod |m|, where |r| and |a| may be the
* same pointer. It returns one on success and zero on error. */
OPENSSL_EXPORT int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n,
const BIGNUM *m, BN_CTX *ctx);
/* BN_mod_lshift_quick acts like |BN_mod_lshift| but requires that |a| be
* non-negative and less than |m|. */
OPENSSL_EXPORT int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n,
const BIGNUM *m);
/* BN_mod_lshift1 sets |r| = (|a| << 1) mod |m|, where |r| and |a| may be the
* same pointer. It returns one on success and zero on error. */
OPENSSL_EXPORT int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m,
BN_CTX *ctx);
/* BN_mod_lshift1_quick acts like |BN_mod_lshift1| but requires that |a| be
* non-negative and less than |m|. */
OPENSSL_EXPORT int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a,
const BIGNUM *m);
/* BN_mod_sqrt returns a |BIGNUM|, r, such that r^2 == a (mod p). */
OPENSSL_EXPORT BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p,
BN_CTX *ctx);
/* Random and prime number generation. */
/* BN_rand sets |rnd| to a random number of length |bits|. If |top| is zero, the
* most-significant bit, if any, will be set. If |top| is one, the two most
* significant bits, if any, will be set.
*
* If |top| is -1 then no extra action will be taken and |BN_num_bits(rnd)| may
* not equal |bits| if the most significant bits randomly ended up as zeros.
*
* If |bottom| is non-zero, the least-significant bit, if any, will be set. The
* function returns one on success or zero otherwise. */
OPENSSL_EXPORT int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);
/* BN_pseudo_rand is an alias for |BN_rand|. */
OPENSSL_EXPORT int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom);
/* BN_rand_range sets |rnd| to a random value [0..range). It returns one on
* success and zero otherwise. */
OPENSSL_EXPORT int BN_rand_range(BIGNUM *rnd, const BIGNUM *range);
/* BN_pseudo_rand_range is an alias for BN_rand_range. */
OPENSSL_EXPORT int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range);
/* BN_generate_dsa_nonce generates a random number 0 <= out < range. Unlike
* BN_rand_range, it also includes the contents of |priv| and |message| in the
* generation so that an RNG failure isn't fatal as long as |priv| remains
* secret. This is intended for use in DSA and ECDSA where an RNG weakness
* leads directly to private key exposure unless this function is used.
* It returns one on success and zero on error. */
OPENSSL_EXPORT int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range,
const BIGNUM *priv,
const uint8_t *message,
size_t message_len, BN_CTX *ctx);
/* BN_GENCB holds a callback function that is used by generation functions that
* can take a very long time to complete. Use |BN_GENCB_set| to initialise a
* |BN_GENCB| structure.
*
* The callback receives the address of that |BN_GENCB| structure as its last
* argument and the user is free to put an arbitary pointer in |arg|. The other
* arguments are set as follows:
* event=BN_GENCB_GENERATED, n=i: after generating the i'th possible prime
* number.
* event=BN_GENCB_PRIME_TEST, n=-1: when finished trial division primality
* checks.
* event=BN_GENCB_PRIME_TEST, n=i: when the i'th primality test has finished.
*
* The callback can return zero to abort the generation progress or one to
* allow it to continue.
*
* When other code needs to call a BN generation function it will often take a
* BN_GENCB argument and may call the function with other argument values. */
#define BN_GENCB_GENERATED 0
#define BN_GENCB_PRIME_TEST 1
struct bn_gencb_st {
void *arg; /* callback-specific data */
int (*callback)(int event, int n, struct bn_gencb_st *);
};
/* BN_GENCB_set configures |callback| to call |f| and sets |callout->arg| to
* |arg|. */
OPENSSL_EXPORT void BN_GENCB_set(BN_GENCB *callback,
int (*f)(int event, int n,
struct bn_gencb_st *),
void *arg);
/* BN_GENCB_call calls |callback|, if not NULL, and returns the return value of
* the callback, or 1 if |callback| is NULL. */
OPENSSL_EXPORT int BN_GENCB_call(BN_GENCB *callback, int event, int n);
/* BN_generate_prime_ex sets |ret| to a prime number of |bits| length. If safe
* is non-zero then the prime will be such that (ret-1)/2 is also a prime.
* (This is needed for Diffie-Hellman groups to ensure that the only subgroups
* are of size 2 and (p-1)/2.).
*
* If |add| is not NULL, the prime will fulfill the condition |ret| % |add| ==
* |rem| in order to suit a given generator. (If |rem| is NULL then |ret| %
* |add| == 1.)
*
* If |cb| is not NULL, it will be called during processing to give an
* indication of progress. See the comments for |BN_GENCB|. It returns one on
* success and zero otherwise. */
OPENSSL_EXPORT int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe,
const BIGNUM *add, const BIGNUM *rem,
BN_GENCB *cb);
/* BN_prime_checks is magic value that can be used as the |checks| argument to
* the primality testing functions in order to automatically select a number of
* Miller-Rabin checks that gives a false positive rate of ~2^{-80}. */
#define BN_prime_checks 0
/* BN_primality_test sets |*is_probably_prime| to one if |candidate| is
* probably a prime number by the Miller-Rabin test or zero if it's certainly
* not.
*
* If |do_trial_division| is non-zero then |candidate| will be tested against a
* list of small primes before Miller-Rabin tests. The probability of this
* function returning a false positive is 2^{2*checks}. If |checks| is
* |BN_prime_checks| then a value that results in approximately 2^{-80} false
* positive probability is used. If |cb| is not NULL then it is called during
* the checking process. See the comment above |BN_GENCB|.
*
* The function returns one on success and zero on error.
*
* (If you are unsure whether you want |do_trial_division|, don't set it.) */
OPENSSL_EXPORT int BN_primality_test(int *is_probably_prime,
const BIGNUM *candidate, int checks,
BN_CTX *ctx, int do_trial_division,
BN_GENCB *cb);
/* BN_is_prime_fasttest_ex returns one if |candidate| is probably a prime
* number by the Miller-Rabin test, zero if it's certainly not and -1 on error.
*
* If |do_trial_division| is non-zero then |candidate| will be tested against a
* list of small primes before Miller-Rabin tests. The probability of this
* function returning one when |candidate| is composite is 2^{2*checks}. If
* |checks| is |BN_prime_checks| then a value that results in approximately
* 2^{-80} false positive probability is used. If |cb| is not NULL then it is
* called during the checking process. See the comment above |BN_GENCB|.
*
* WARNING: deprecated. Use |BN_primality_test|. */
OPENSSL_EXPORT int BN_is_prime_fasttest_ex(const BIGNUM *candidate, int checks,
BN_CTX *ctx, int do_trial_division,
BN_GENCB *cb);
/* BN_is_prime_ex acts the same as |BN_is_prime_fasttest_ex| with
* |do_trial_division| set to zero.
*
* WARNING: deprecated: Use |BN_primality_test|. */
OPENSSL_EXPORT int BN_is_prime_ex(const BIGNUM *candidate, int checks,
BN_CTX *ctx, BN_GENCB *cb);
/* Number theory functions */
/* BN_gcd sets |r| = gcd(|a|, |b|). It returns one on success and zero
* otherwise. */
OPENSSL_EXPORT int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
BN_CTX *ctx);
/* BN_mod_inverse sets |out| equal to |a|^-1, mod |n|. If either of |a| or |n|
* have |BN_FLG_CONSTTIME| set then the operation is performed in constant
* time. If |out| is NULL, a fresh BIGNUM is allocated. It returns the result
* or NULL on error. */
OPENSSL_EXPORT BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a,
const BIGNUM *n, BN_CTX *ctx);
/* BN_kronecker returns the Kronecker symbol of |a| and |b| (which is -1, 0 or
* 1), or -2 on error. */
OPENSSL_EXPORT int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
/* Montgomery arithmetic. */
/* BN_MONT_CTX contains the precomputed values needed to work in a specific
* Montgomery domain. */
/* BN_MONT_CTX_new returns a fresh BN_MONT_CTX or NULL on allocation failure. */
OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_new(void);
/* BN_MONT_CTX_init initialises a stack allocated |BN_MONT_CTX|. */
OPENSSL_EXPORT void BN_MONT_CTX_init(BN_MONT_CTX *mont);
/* BN_MONT_CTX_free frees the contexts of |mont| and, if it was originally
* allocated with |BN_MONT_CTX_new|, |mont| itself. */
OPENSSL_EXPORT void BN_MONT_CTX_free(BN_MONT_CTX *mont);
/* BN_MONT_CTX_copy sets |to| equal to |from|. It returns |to| on success or
* NULL on error. */
OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to,
BN_MONT_CTX *from);
/* BN_MONT_CTX_set sets up a Montgomery context given the modulus, |mod|. It
* returns one on success and zero on error. */
OPENSSL_EXPORT int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod,
BN_CTX *ctx);
/* BN_MONT_CTX_set_locked takes |lock| and checks whether |*pmont| is NULL. If
* so, it creates a new |BN_MONT_CTX| and sets the modulus for it to |mod|. It
* then stores it as |*pmont| and returns it, or NULL on error.
*
* If |*pmont| is already non-NULL then the existing value is returned. */
BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock,
const BIGNUM *mod, BN_CTX *bn_ctx);
/* BN_to_montgomery sets |ret| equal to |a| in the Montgomery domain. It
* returns one on success and zero on error. */
OPENSSL_EXPORT int BN_to_montgomery(BIGNUM *ret, const BIGNUM *a,
const BN_MONT_CTX *mont, BN_CTX *ctx);
/* BN_from_montgomery sets |ret| equal to |a| * R^-1, i.e. translates values
* out of the Montgomery domain. It returns one on success or zero on error. */
OPENSSL_EXPORT int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a,
const BN_MONT_CTX *mont, BN_CTX *ctx);
/* BN_mod_mul_montgomery set |r| equal to |a| * |b|, in the Montgomery domain.
* Both |a| and |b| must already be in the Montgomery domain (by
* |BN_to_montgomery|). It returns one on success or zero on error. */
OPENSSL_EXPORT int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a,
const BIGNUM *b,
const BN_MONT_CTX *mont, BN_CTX *ctx);
/* Exponentiation. */
/* BN_exp sets |r| equal to |a|^{|p|}. It does so with a square-and-multiply
* algorithm that leaks side-channel information. It returns one on success or
* zero otherwise. */
OPENSSL_EXPORT int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
BN_CTX *ctx);
/* BN_mod_exp sets |r| equal to |a|^{|p|} mod |m|. It does so with the best
* algorithm for the values provided and can run in constant time if
* |BN_FLG_CONSTTIME| is set for |p|. It returns one on success or zero
* otherwise. */
OPENSSL_EXPORT int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx);
OPENSSL_EXPORT int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx,
BN_MONT_CTX *m_ctx);
OPENSSL_EXPORT int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a,
const BIGNUM *p, const BIGNUM *m,
BN_CTX *ctx, BN_MONT_CTX *in_mont);
OPENSSL_EXPORT int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx,
BN_MONT_CTX *m_ctx);
OPENSSL_EXPORT int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1,
const BIGNUM *p1, const BIGNUM *a2,
const BIGNUM *p2, const BIGNUM *m,
BN_CTX *ctx, BN_MONT_CTX *m_ctx);
/* Private functions */
struct bignum_st {
BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit chunks in little-endian
order. */
int top; /* Index of last used element in |d|, plus one. */
int dmax; /* Size of |d|, in words. */
int neg; /* one if the number is negative */
int flags; /* bitmask of BN_FLG_* values */
};
struct bn_mont_ctx_st {
BIGNUM RR; /* used to convert to montgomery form */
BIGNUM N; /* The modulus */
BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1
* (Ni is only stored for bignum algorithm) */
BN_ULONG n0[2]; /* least significant word(s) of Ni;
(type changed with 0.9.9, was "BN_ULONG n0;" before) */
int flags;
int ri; /* number of bits in R */
};
OPENSSL_EXPORT unsigned BN_num_bits_word(BN_ULONG l);
#define BN_FLG_MALLOCED 0x01
#define BN_FLG_STATIC_DATA 0x02
/* avoid leaking exponent information through timing, BN_mod_exp_mont() will
* call BN_mod_exp_mont_consttime, BN_div() will call BN_div_no_branch,
* BN_mod_inverse() will call BN_mod_inverse_no_branch. */
#define BN_FLG_CONSTTIME 0x04
/* Android compatibility section.
*
* These functions are declared, temporarily, for Android because
* wpa_supplicant will take a little time to sync with upstream. Outside of
* Android they'll have no definition. */
OPENSSL_EXPORT BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn);
#if defined(__cplusplus)
} /* extern C */
#endif
#define BN_F_BN_CTX_get 100
#define BN_F_BN_CTX_new 101
#define BN_F_BN_CTX_start 102
#define BN_F_BN_bn2dec 103
#define BN_F_BN_bn2hex 104
#define BN_F_BN_div 105
#define BN_F_BN_div_recp 106
#define BN_F_BN_exp 107
#define BN_F_BN_generate_dsa_nonce 108
#define BN_F_BN_generate_prime_ex 109
#define BN_F_BN_mod_exp2_mont 110
#define BN_F_BN_mod_exp_mont 111
#define BN_F_BN_mod_exp_mont_consttime 112
#define BN_F_BN_mod_exp_mont_word 113
#define BN_F_BN_mod_inverse 114
#define BN_F_BN_mod_inverse_no_branch 115
#define BN_F_BN_mod_lshift_quick 116
#define BN_F_BN_mod_sqrt 117
#define BN_F_BN_new 118
#define BN_F_BN_rand 119
#define BN_F_BN_rand_range 120
#define BN_F_BN_sqrt 121
#define BN_F_BN_usub 122
#define BN_F_bn_wexpand 123
#define BN_F_mod_exp_recp 124
#define BN_F_BN_lshift 125
#define BN_F_BN_rshift 126
#define BN_R_ARG2_LT_ARG3 100
#define BN_R_BAD_RECIPROCAL 101
#define BN_R_BIGNUM_TOO_LONG 102
#define BN_R_BITS_TOO_SMALL 103
#define BN_R_CALLED_WITH_EVEN_MODULUS 104
#define BN_R_DIV_BY_ZERO 105
#define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 106
#define BN_R_INPUT_NOT_REDUCED 107
#define BN_R_INVALID_RANGE 108
#define BN_R_NEGATIVE_NUMBER 109
#define BN_R_NOT_A_SQUARE 110
#define BN_R_NOT_INITIALIZED 111
#define BN_R_NO_INVERSE 112
#define BN_R_PRIVATE_KEY_TOO_LARGE 113
#define BN_R_P_IS_NOT_PRIME 114
#define BN_R_TOO_MANY_ITERATIONS 115
#define BN_R_TOO_MANY_TEMPORARY_VARIABLES 116
#endif /* OPENSSL_HEADER_BN_H */

@ -1,123 +0,0 @@
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
#ifndef OPENSSL_HEADER_BUFFER_H
#define OPENSSL_HEADER_BUFFER_H
#include <openssl/base.h>
#if defined(__cplusplus)
extern "C" {
#endif
/* Memory and string functions, see also mem.h. */
/* BUF_MEM is a generic buffer object used by OpenSSL. */
struct buf_mem_st {
size_t length; /* current number of bytes */
char *data;
size_t max; /* size of buffer */
};
/* BUF_MEM_new creates a new BUF_MEM which has no allocated data buffer. */
OPENSSL_EXPORT BUF_MEM *BUF_MEM_new(void);
/* BUF_MEM_free frees |buf->data| if needed and then frees |buf| itself. */
OPENSSL_EXPORT void BUF_MEM_free(BUF_MEM *buf);
/* BUF_MEM_grow ensures that |buf| has length |len| and allocates memory if
* needed. If the length of |buf| increased, the new bytes are filled with
* zeros. It returns the length of |buf|, or zero if there's an error. */
OPENSSL_EXPORT size_t BUF_MEM_grow(BUF_MEM *buf, size_t len);
/* BUF_MEM_grow_clean acts the same as |BUF_MEM_grow|, but clears the previous
* contents of memory if reallocing. */
OPENSSL_EXPORT size_t BUF_MEM_grow_clean(BUF_MEM *str, size_t len);
/* BUF_strdup returns an allocated, duplicate of |str|. */
OPENSSL_EXPORT char *BUF_strdup(const char *str);
/* BUF_strnlen returns the number of characters in |str|, excluding the NUL
* byte, but at most |max_len|. This function never reads more than |max_len|
* bytes from |str|. */
OPENSSL_EXPORT size_t BUF_strnlen(const char *str, size_t max_len);
/* BUF_strndup returns an allocated, duplicate of |str|, which is, at most,
* |size| bytes. The result is always NUL terminated. */
OPENSSL_EXPORT char *BUF_strndup(const char *str, size_t size);
/* BUF_memdup returns an allocated, duplicate of |size| bytes from |data|. */
OPENSSL_EXPORT void *BUF_memdup(const void *data, size_t size);
/* BUF_strlcpy acts like strlcpy(3). */
OPENSSL_EXPORT size_t BUF_strlcpy(char *dst, const char *src, size_t dst_size);
/* BUF_strlcat acts like strlcat(3). */
OPENSSL_EXPORT size_t BUF_strlcat(char *dst, const char *src, size_t size);
#if defined(__cplusplus)
} /* extern C */
#endif
#define BUF_F_BUF_MEM_new 100
#define BUF_F_BUF_memdup 101
#define BUF_F_BUF_strndup 102
#define BUF_F_buf_mem_grow 103
#endif /* OPENSSL_HEADER_BUFFER_H */

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save